[basic.link] (original) (raw)

6 Basics [basic]

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:

A name having namespace scope has internal linkage if it is the name of

[ 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

has its linkage determined as follows:

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;
void g() { extern void f();
extern void h();
int i;
{ extern void f();
extern int i;
} }

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();
extern void q();
}

void middle() { q();
}

void q() { }
}

void 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.pre]) and that are declared in different scopes shall denote the same variable, function, type, template or namespace if

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

:

Enumerators do not have linkage, but may serve as the name of an enumeration with linkage ([dcl.enum]).

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();
int g();

Module interface of M:

module; #include "decls.h" export module M; export using ::f;
int g();
export int h();
export int k();

Other translation unit:

import M; static int h();
int k();

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 whichtypedefs 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.

A declaration D names an entity E if

A declaration is an exposureif it either names a TU-local entity (defined below), ignoring

or defines a constexpr variable initialized to a TU-local value (defined below).

[ Note

:

An inline function template can be an exposure even though explicit specializations of it might be usable in other translation units.

end note

]

An entity is TU-local if it is

A value or object is TU-local if either

If a (possibly instantiated) declaration of, or a deduction guide for, a non-TU-local entity in a module interface unit (outside the private-module-fragment, if any) or module partition ([module.unit]) is an exposure, the program is ill-formed.

Such a declaration in any other context is deprecated ([depr.local]).

If a declaration that appears in one translation unit names a TU-local entity declared in another translation unit that is not a header unit, the program is ill-formed.

A declaration instantiated for a template specialization ([temp.spec]) appears at the point of instantiation of the specialization ([temp.point]).

[ Example

:

Translation unit #1:

export module A; static void f() {} inline void it() { f(); }
static inline void its() { f(); }
template void g() { its(); }
template void g<0>();

decltype(f) *fp;
auto &fr = f;
constexpr auto &fr2 = fr;
constexpr static auto fp2 = fr;

struct S { void (&ref)(); } s{f};
constexpr extern struct W { S &s; } wrap{s};

static auto x = []{f();};
auto x2 = x;
int y = ([]{f();}(),0);
int y2 = (x,0);

namespace N { struct A {}; void adl(A); static void adl(int); } void adl(double);

inline void h(auto x) { adl(x); }

Translation unit #2:

module A; void other() { g<0>();
g<1>();
h(N::A{});
h(0);
adl(N::A{});
fr();
constexpr auto ptr = fr;
}

end example

]