[basic.link] (original) (raw)

6 Basics [basic]

A translation unit consists of a sequence of declarations.

A name can haveexternal linkage,module linkage,internal linkage, orno linkage, as determined by the rules below.

[Note 1:

All declarations of an entity with a name with internal linkage appear in the same translation unit.

All declarations of an entity with module linkage are attached to the same module.

— _end note_]

The name of an entity that belongs to a namespace scopehas internal linkage if it is the name of

[Note 2:

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.

The name of an entity that belongs to a 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, a static data member, a named class or enumeration that inhabits a class scope, or an unnamed class or enumeration defined in a typedef declaration that inhabits a class scope 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.

[Example 1: static void f();extern "C" void h();static int i = 0; void q() { extern void f(); extern void g(); extern void h(); int i; { extern void f(); extern int i; } }

Even though the declaration at line #2 hides the declaration at line #1, the declaration at line #3 still redeclares #1 and receives internal linkage.

— _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 declarations of entities declare the same entity if, considering declarations of unnamed types to introduce their names for linkage purposes, if any ([dcl.typedef], [dcl.enum]), they correspond ([basic.scope.scope]), have the same target scope that is not a function or template parameter scope, neither is a name-independent declaration, and either

If a declaration H that declares a name with internal linkage precedes a declaration D in another translation unit U and would declare the same entity as D if it appeared in U, the program is ill-formed.

[Note 4:

Such an H can appear only in a header unit.

— _end note_]

If two declarations of an entity are attached to different modules, the program is ill-formed; no diagnostic is required if neither is reachable from the other.

[Example 2:

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

For any two declarations of an entity E:

Types are compared after all adjustments of types (during which typedefs ([dcl.typedef]) are replaced by their definitions); declarations for an array object can specify array types that differ by the presence or absence of a major array bound ([dcl.array]).

No diagnostic is required if neither declaration is reachable from the other.

[Example 3: int f(int x, int x); void g(); void g(int); int g(); void h(); namespace h {} — _end example_]

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 8:

An inline function template can be an exposure even though certain explicit specializations of it would 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 4:

Translation unit #1:export module A;static void f() {} inline void it() { f(); } static inline void its() { f(); } template<int> 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_]