6 Basics [basic]

6.5 Program and linkage [basic.link]

A program consists of one or more translation units linked together.
A translation unit consists of a sequence of declarations.
translation-unit:
	top-level-declaration-seq
	global-module-fragment module-declaration top-level-declaration-seq private-module-fragment
private-module-fragment:
	module : private ; top-level-declaration-seq
top-level-declaration-seq:
	top-level-declaration
	top-level-declaration-seq top-level-declaration
top-level-declaration:
	module-import-declaration
	declaration
A private-module-fragment shall appear only in a primary module interface unit ([module.unit]).
A module unit with a private-module-fragment shall be the only module unit of its module; no diagnostic is required.
A token sequence beginning with export module and not immediately followed by ​::​ is never interpreted as the declaration of a top-level-declaration.
A name is said to have linkage when it might denote the same object, reference, function, type, template, namespace or value as a name introduced by a declaration in another scope:
  • When a name has external linkage, the entity it denotes can be referred to by names from scopes of other translation units or from other scopes of the same translation unit.
  • When a name has module linkage, the entity it denotes can be referred to by names from other scopes of the same module unit ([module.unit]) or from scopes of other module units of that same module.
  • When a name has internal linkage, the entity it denotes can be referred to by names from other scopes in the same translation unit.
  • When a name has no linkage, the entity it denotes cannot be referred to by names from other scopes.
A name having namespace scope has internal linkage if it is the name of
  • a variable, variable template, function, or function template that is explicitly declared static; or
  • a non-template variable of non-volatile const-qualified type, unless
    • it is explicitly declared extern, or
    • it is inline or exported, or
    • it was previously declared and the prior declaration did not have internal linkage; or
  • a data member of an anonymous union.
Note
:
An instantiated variable template that has const-qualified type can have external or module linkage, even if not declared extern.
— end note
 ]
An unnamed namespace or a namespace declared directly or indirectly within an unnamed namespace has internal linkage.
All other namespaces have external linkage.
A name having namespace scope that has not been given internal linkage above and that is the name of
  • a variable; or
  • a function; or
  • a named class ([class]), or an unnamed class defined in a typedef declaration in which the class has the typedef name for linkage purposes ([dcl.typedef]); or
  • a named enumeration, or an unnamed enumeration defined in a typedef declaration in which the enumeration has the typedef name for linkage purposes ([dcl.typedef]); or
  • a template
has its linkage determined as follows:
  • if the enclosing namespace has internal linkage, the name has internal linkage;
  • otherwise, if the declaration of the name is attached to a named module ([module.unit]) and is not exported ([module.interface]), the name has module linkage;
  • otherwise, the name has external linkage.
In addition, a member function, static data member, a named class or enumeration of class scope, or an unnamed class or enumeration defined in a class-scope typedef declaration such that the class or enumeration has the typedef name for linkage purposes ([dcl.typedef]), has the same linkage, if any, as the name of the class of which it is a member.
The name of a function declared in block scope and the name of a variable declared by a block scope extern declaration have linkage.
If such a declaration is attached to a named module, the program is ill-formed.
If there is a visible declaration of an entity with linkage, ignoring entities declared outside the innermost enclosing namespace scope, such that the block scope declaration would be a (possibly ill-formed) redeclaration if the two declarations appeared in the same declarative region, the block scope declaration declares that same entity and receives the linkage of the previous declaration.
If there is more than one such matching entity, the program is ill-formed.
Otherwise, if no matching entity is found, the block scope entity receives external linkage.
If, within a translation unit, the same entity is declared with both internal and external linkage, the program is ill-formed.
Example
:
static void f();
extern "C" void h();
static int i = 0;               // #1
void g() {
  extern void f();              // internal linkage
  extern void h();              // C language linkage
  int i;                        // #2: i has no linkage
  {
    extern void f();            // internal linkage
    extern int i;               // #3: external linkage, ill-formed
  }
}
Without the declaration at line #2, the declaration at line #3 would link with the declaration at line #1.
Because the declaration with internal linkage is hidden, however, #3 is given external linkage, making the program ill-formed.
— end example
 ]
When a block scope declaration of an entity with linkage is not found to refer to some other declaration, then that entity is a member of the innermost enclosing namespace.
However such a declaration does not introduce the member name in its namespace scope.
Example
:
namespace X {
  void p() {
    q();                        // error: q not yet declared
    extern void q();            // q is a member of namespace X
  }

  void middle() {
    q();                        // error: q not yet declared
  }

  void q() { /* ... */ }        // definition of X​::​q
}

void q() { /* ... */ }          // some other, unrelated q
— end example
 ]
Names not covered by these rules have no linkage.
Moreover, except as noted, a name declared at block scope has no linkage.
Two names that are the same ([basic]) and that are declared in different scopes shall denote the same variable, function, type, template or namespace if
  • both names have external or module linkage and are declared in declarations attached to the same module, or else both names have internal linkage and are declared in the same translation unit; and
  • both names refer to members of the same namespace or to members, not by inheritance, of the same class; and
  • when both names denote functions, the parameter-type-lists of the functions ([dcl.fct]) are identical; and
  • when both names denote function templates, the signatures ([temp.over.link]) are the same.
If multiple declarations of the same name with external linkage would declare the same entity except that they are attached to different modules, the program is ill-formed; no diagnostic is required.
Note
:
using-declarations, typedef declarations, and alias-declarations do not declare entities, but merely introduce synonyms.
Similarly, using-directives do not declare entities.
— end note
 ]
If a declaration would redeclare a reachable declaration attached to a different module, the program is ill-formed.
Example
:

"decls.h":

int f();            // #1, attached to the global module
int g();            // #2, attached to the global module

Module interface of M:

module;
#include "decls.h"
export module M;
export using ::f;   // OK: does not declare an entity, exports #1
int g();            // error: matches #2, but attached to M
export int h();     // #3
export int k();     // #4

Other translation unit:

import M;
static int h();     // error: matches #3
int k();            // error: matches #4
— end example
 ]
As a consequence of these rules, all declarations of an entity are attached to the same module; the entity is said to be attached to that module.
After all adjustments of types (during which typedefs are replaced by their definitions), the types specified by all declarations referring to a given variable or function shall be identical, except that declarations for an array object can specify array types that differ by the presence or absence of a major array bound ([dcl.array]).
A violation of this rule on type identity does not require a diagnostic.
Note
:
Linkage to non-C++ declarations can be achieved using a linkage-specification.
— end note
 ]