The gist
| Linkage | Where the identifier can be used | Same name in another file |
|---|---|---|
| Internal | Only within its own translation unit | Refers to an independent entity |
| External | From other translation units via a declaration | Refers to the same shared entity |
Defaults at a glance
| Identifier at global scope | Default linkage | Make it internal | Make it external |
|---|---|---|---|
| Non-constant variable | External | static or unnamed namespace |
Nothing—already external |
const variable |
Internal | Nothing—already internal | extern on its initialized definition |
constexpr variable |
Internal | Nothing—already internal | Possible with extern, but rarely useful |
| Function | External | static or unnamed namespace |
Nothing—already external |
Internal linkage
Use internal linkage for globals, helper functions, and types that are implementation details of one translation unit:
namespace
{
int g_count {};
int add(int x, int y)
{
return x + y;
}
}
const int maxItems { 10 }; // internal by default
constexpr int retries { 3 }; // internal by default
An unnamed namespace works for many kinds of identifiers and is convenient when several names should be internal. static is another option for a global variable or function:
static int g_count {};
static int add(int x, int y);
Two files may define internal identifiers with the same name. They are separate entities, so this does not violate the one-definition rule.
External linkage
Use external linkage when multiple translation units must use the same entity. Put declarations in a header and one definition in a source file:
// globals.h — declarations
extern int g_count;
extern const int maxItems;
void sayHi();
// globals.cpp — the one set of definitions
int g_count {};
extern const int maxItems { 10 };
void sayHi()
{
// ...
}
Other source files include the header. The compiler sees the declarations, and the linker connects each use to the definitions.
External non-constant globals and functions are external by default. Avoid writing extern on their definitions; reserve it for variable declarations and definitions of external const globals.
Choosing quickly
- Used only in this translation unit? Give it internal linkage.
- Used by multiple translation units? Give it external linkage, declare it in a header, and define it once in a source file.
- Internal definitions with the same name in different files are independent.
- An ordinary external object or function must have only one definition in the program.