Files
2025-10-25 03:02:53 +03:00

525 lines
22 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[basic.link]
# 6 Basics [[basic]](./#basic)
## 6.7 Program and linkage [basic.link]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2876)
A [*program*](#def:program "6.7Program and linkage[basic.link]") consists of one or more [translation units](lex.separate#def:translation_unit "5.1Separate translation[lex.separate]") linked together[.](#1.sentence-1)
A translation unit consists
of a sequence of declarations[.](#1.sentence-2)
[translation-unit:](#nt:translation-unit "6.7Program and linkage[basic.link]")
[*declaration-seq*](dcl.pre#nt:declaration-seq "9.1Preamble[dcl.pre]")opt
[*global-module-fragment*](module.global.frag#nt:global-module-fragment "10.4Global module fragment[module.global.frag]")opt [*module-declaration*](module.unit#nt:module-declaration "10.1Module units and purviews[module.unit]") [*declaration-seq*](dcl.pre#nt:declaration-seq "9.1Preamble[dcl.pre]")opt [*private-module-fragment*](module.private.frag#nt:private-module-fragment "10.5Private module fragment[module.private.frag]")opt
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2889)
A name has[*external linkage*](#def:linkage,external "6.7Program and linkage[basic.link]"),[*module linkage*](#def:linkage,module "6.7Program and linkage[basic.link]"),[*internal linkage*](#def:linkage,internal "6.7Program and linkage[basic.link]"), or[*no linkage*](#def:linkage,no "6.7Program and linkage[basic.link]"),
as determined by the rules below[.](#2.sentence-1)
[*Note [1](#note-1)*:
All declarations of an entity with a name with internal linkage
appear in the same translation unit[.](#2.sentence-2)
All declarations of an entity with module linkage
are attached to the same module[.](#2.sentence-3)
— *end note*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2904)
The name of an entity
that belongs to a [namespace scope](basic.scope.namespace "6.4.6Namespace scope[basic.scope.namespace]") has internal linkage if it is the name of
- [(3.1)](#3.1)
a variable, variable template, function, or function template that is
explicitly declared static; or
- [(3.2)](#3.2)
a non-template variable of non-volatile const-qualified type, unless
* [(3.2.1)](#3.2.1)
it is declared in the purview of a module interface unit
(outside the [*private-module-fragment*](module.private.frag#nt:private-module-fragment "10.5Private module fragment[module.private.frag]"), if any) or
module partition, or
* [(3.2.2)](#3.2.2)
it is explicitly declared extern, or
* [(3.2.3)](#3.2.3)
it is inline, or
* [(3.2.4)](#3.2.4)
it was previously declared and the prior declaration did
not have internal linkage; or
- [(3.3)](#3.3)
a data member of an anonymous union[.](#3.sentence-1)
[*Note [2](#note-2)*:
An instantiated variable template that has const-qualified type
can have external or module linkage, even if not declared extern[.](#3.sentence-2)
— *end note*]
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2937)
An unnamed namespace or a namespace declared directly or indirectly within an
unnamed namespace has internal linkage[.](#4.sentence-1)
All other namespaces have external linkage[.](#4.sentence-2)
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
- [(4.1)](#4.1)
a variable; or
- [(4.2)](#4.2)
a function; or
- [(4.3)](#4.3)
a named class ([[class.pre]](class.pre "11.1Preamble")), or an unnamed class defined in a
typedef declaration in which the class has the typedef name for linkage
purposes ([[dcl.typedef]](dcl.typedef "9.2.4The typedef specifier")); or
- [(4.4)](#4.4)
a named [enumeration](dcl.enum "9.8.1Enumeration declarations[dcl.enum]"), or an unnamed enumeration defined
in a typedef declaration in which the enumeration has the typedef name
for linkage purposes ([[dcl.typedef]](dcl.typedef "9.2.4The typedef specifier")); or
- [(4.5)](#4.5)
an unnamed enumeration
that has an enumerator as a name for linkage purposes ([[dcl.enum]](dcl.enum "9.8.1Enumeration declarations")); or
- [(4.6)](#4.6)
a template
has its linkage determined as follows:
- [(4.7)](#4.7)
if the entity is a function or function template
first declared in a friend declaration and
that declaration is a definition and
the enclosing class is defined within an [*export-declaration*](module.interface#nt:export-declaration "10.2Export declaration[module.interface]"),
the name has the same linkage, if any,
as the name of the enclosing class ([[class.friend]](class.friend "11.8.4Friends"));
- [(4.8)](#4.8)
otherwise,if the entity is a function or function template
declared in a friend declaration and
a corresponding non-friend declaration is reachable,
the name has the linkage determined from that prior declaration,
- [(4.9)](#4.9)
otherwise,
if the enclosing namespace has internal linkage,
the name has internal linkage;
- [(4.10)](#4.10)
otherwise,
if the declaration of the name is
attached to a named module ([[module.unit]](module.unit "10.1Module units and purviews"))
and is not exported ([[module.interface]](module.interface "10.2Export declaration")),
the name has module linkage;
- [(4.11)](#4.11)
otherwise,
the name has external linkage[.](#4.sentence-3)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2994)
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]](dcl.typedef "9.2.4The typedef specifier")),
has the same linkage, if any, as the name of the class of which it is a member[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3005)
[*Example [1](#example-1)*: static void f();extern "C" void h();static int i = 0; // #1void q() {extern void f(); // internal linkageextern void g(); // ::g, external linkageextern void h(); // C language linkageint i; // #2: i has no linkage{extern void f(); // internal linkageextern int i; // #3: internal linkage}}
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[.](#6.sentence-1)
— *end example*]
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3026)
Names not covered by these rules have no linkage[.](#7.sentence-1)
Moreover, except as
noted, a name declared at [block scope](basic.scope.block#def:scope,block "6.4.3Block scope[basic.scope.block]") has no
linkage[.](#7.sentence-2)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3032)
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.typedef "9.2.4The typedef specifier"), [[dcl.enum]](dcl.enum "9.8.1Enumeration declarations")),
they correspond ([[basic.scope.scope]](basic.scope.scope "6.4.1General")),
have the same target scope that is not a function or template parameter scope,
neither is a name-independent declaration,
and either
- [(8.1)](#8.1)
they appear in the same translation unit, or
- [(8.2)](#8.2)
they both declare type aliases or namespace aliases that have the same underlying entity, or
- [(8.3)](#8.3)
they both declare names with module linkage and are attached to the same module, or
- [(8.4)](#8.4)
they both declare names with external linkage[.](#8.sentence-1)
[*Note [3](#note-3)*:
There are other circumstances in which declarations declare
the same entity ([[dcl.link]](dcl.link "9.12Linkage specifications"), [[temp.type]](temp.type "13.6Type equivalence"), [[temp.spec.partial]](temp.spec.partial "13.7.6Partial specialization"))[.](#8.sentence-2)
— *end note*]
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3055)
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[.](#9.sentence-1)
[*Note [4](#note-4)*:
Such an H can appear only in a header unit[.](#9.sentence-2)
— *end note*]
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3064)
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[.](#10.sentence-1)
[*Example [2](#example-2)*:
"decls.h":int f(); // #1, attached to the global moduleint 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 #1int g(); // error: matches #2, but attached to Mexport int h(); // #3export int k(); // #4
Other translation unit:import M;static int h(); // error: matches #3int 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*](#def:attached,entity "6.7Program and linkage[basic.link]") to that module[.](#10.sentence-2)
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3094)
For any two declarations of an entity E:
- [(11.1)](#11.1)
If one declares E to be a variable or function,
the other shall declare E as one of the same type[.](#11.1.sentence-1)
- [(11.2)](#11.2)
If one declares E to be an enumerator, the other shall do so[.](#11.2.sentence-1)
- [(11.3)](#11.3)
If one declares E to be a namespace, the other shall do so[.](#11.3.sentence-1)
- [(11.4)](#11.4)
If one declares E to be a type,
the other shall declare E to be a type of the same kind ([[dcl.type.elab]](dcl.type.elab "9.2.9.5Elaborated type specifiers"))[.](#11.4.sentence-1)
- [(11.5)](#11.5)
If one declares E to be a class template,
the other shall do so with the same kind and
an equivalent [*template-head*](temp.pre#nt:template-head "13.1Preamble[temp.pre]") ([[temp.over.link]](temp.over.link "13.7.7.2Function template overloading"))[.](#11.5.sentence-1)
[*Note [5](#note-5)*:
The declarations can supply different default template arguments[.](#11.5.sentence-2)
— *end note*]
- [(11.6)](#11.6)
If one declares E to be a function template or
a (partial specialization of a) variable template,
the other shall declare E to be one
with an equivalent [*template-head*](temp.pre#nt:template-head "13.1Preamble[temp.pre]") and type[.](#11.6.sentence-1)
- [(11.7)](#11.7)
If one declares E to be an alias template,
the other shall declare E to be one with
an equivalent [*template-head*](temp.pre#nt:template-head "13.1Preamble[temp.pre]") and [*defining-type-id*](dcl.name#nt:defining-type-id "9.3.2Type names[dcl.name]")[.](#11.7.sentence-1)
- [(11.8)](#11.8)
If one declares E to be a concept, the other shall do so[.](#11.8.sentence-1)
Types are compared after all adjustments of types (during which
typedefs ([[dcl.typedef]](dcl.typedef "9.2.4The typedef specifier")) 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]](dcl.array "9.3.4.5Arrays"))[.](#11.sentence-2)
No diagnostic is required if neither declaration is reachable from the other[.](#11.sentence-3)
[*Example [3](#example-3)*: int f(int x, int x); // error: different entities for xvoid g(); // #1void g(int); // OK, different entity from #1int g(); // error: same entity as #1 with different typevoid h(); // #2namespace h {} // error: same entity as #2, but not a function — *end example*]
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3145)
[*Note [6](#note-6)*:
Linkage to non-C++ declarations can be achieved using a[*linkage-specification*](dcl.link#nt:linkage-specification "9.12Linkage specifications[dcl.link]") ([[dcl.link]](dcl.link "9.12Linkage specifications"))[.](#12.sentence-1)
— *end note*]
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3152)
A declaration D [*names*](#def:name "6.7Program and linkage[basic.link]") an entity E if
- [(13.1)](#13.1)
D contains a [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1General[expr.prim.lambda.general]") whose closure type is E,
- [(13.2)](#13.2)
D contains
a [*reflect-expression*](expr.reflect#nt:reflect-expression "7.6.2.10The reflection operator[expr.reflect]") or a [*splice-specifier*](basic.splice#nt:splice-specifier "6.6Splice specifiers[basic.splice]") that, respectively, represents or designates E,
- [(13.3)](#13.3)
D is an injected declaration ([[expr.const]](expr.const "7.7Constant expressions"))
whose characteristic sequence contains a reflection
that represents
a data member description (T, N, A, W, NUA) ([[class.mem.general]](class.mem.general "11.4.1General"))
for which T is E,
- [(13.4)](#13.4)
E is not a function or function template and D contains an[*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]"),[*type-specifier*](dcl.type.general#nt:type-specifier "9.2.9.1General[dcl.type.general]"),[*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]"),[*template-name*](temp.names#nt:template-name "13.3Names of template specializations[temp.names]"), or[*concept-name*](temp.concept#nt:concept-name "13.7.9Concept definitions[temp.concept]") denoting E, or
- [(13.5)](#13.5)
E is a function or function template andD contains an expression that names E ([[basic.def.odr]](basic.def.odr "6.3One-definition rule")) or
an [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]") that refers to a set of overloads that contains E[.](#13.sentence-1)
[*Note [7](#note-7)*:
Non-dependent names in an instantiated declaration
do not refer to a set of overloads ([[temp.res]](temp.res "13.8Name resolution"))[.](#13.5.sentence-2)
— *end note*]
[14](#14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3186)
A declaration is an [*exposure*](#def:exposure "6.7Program and linkage[basic.link]") if it either names a TU-local entity (defined below), ignoring
- [(14.1)](#14.1)
the [*function-body*](dcl.fct.def.general#nt:function-body "9.6.1General[dcl.fct.def.general]") for a non-inline function or function template
(but not the deduced return type
for a (possibly instantiated) definition of a function
with a declared return type that uses a placeholder type ([[dcl.spec.auto]](dcl.spec.auto "9.2.9.7Placeholder type specifiers"))),
- [(14.2)](#14.2)
the [*initializer*](dcl.init.general#nt:initializer "9.5.1General[dcl.init.general]") for a variable or variable template (but not the variable's type),
- [(14.3)](#14.3)
friend declarations in a class definition, and
- [(14.4)](#14.4)
any reference to a non-volatile const object or reference
with internal or no linkage initialized with a constant expression
that is not an odr-use ([[basic.def.odr]](basic.def.odr#term.odr.use "6.3One-definition rule")),
or defines a constexpr variable initialized to a TU-local value (defined below)[.](#14.sentence-1)
[*Note [8](#note-8)*:
An inline function template can be an exposure even though
certain explicit specializations of it would be usable in other translation units[.](#14.sentence-2)
— *end note*]
[15](#15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3212)
An entity is [*TU-local*](#def:TU-local,entity "6.7Program and linkage[basic.link]") if it is
- [(15.1)](#15.1)
a type, type alias, namespace, namespace alias, function, variable, or template that
* [(15.1.1)](#15.1.1)
has a name with internal linkage, or
* [(15.1.2)](#15.1.2)
does not have a name with linkage and is declared,
or introduced by a [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1General[expr.prim.lambda.general]"),
within the definition of a TU-local entity,
- [(15.2)](#15.2)
a type with no name that is defined outside a[*class-specifier*](class.pre#nt:class-specifier "11.1Preamble[class.pre]"),
function body, or[*initializer*](dcl.init.general#nt:initializer "9.5.1General[dcl.init.general]") or is introduced by a [*defining-type-specifier*](dcl.type.general#nt:defining-type-specifier "9.2.9.1General[dcl.type.general]") that is used to declare only TU-local entities,
- [(15.3)](#15.3)
a specialization of a TU-local template,
- [(15.4)](#15.4)
a specialization of a template with any TU-local template argument, or
- [(15.5)](#15.5)
a specialization of a template
whose (possibly instantiated) declaration is an exposure[.](#15.sentence-1)
[*Note [9](#note-9)*:
A specialization can be produced by implicit or explicit instantiation[.](#15.5.sentence-2)
— *end note*]
[16](#16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3244)
A value or object is [*TU-local*](#def:TU-local,value_or_object "6.7Program and linkage[basic.link]") if either
- [(16.1)](#16.1)
it is of TU-local type,
- [(16.2)](#16.2)
it is, or is a pointer to,
a TU-local function or the object associated with a TU-local variable,
- [(16.3)](#16.3)
it is an object of class or array type and
any of its subobjects or
any of the objects or functions
to which its non-static data members of reference type refer
is TU-local and is usable in constant expressions, or
- [(16.4)](#16.4)
it is a reflection value ([[basic.fundamental]](basic.fundamental "6.9.2Fundamental types")) that represents
* [(16.4.1)](#16.4.1)
an entity, value, or object that is TU-local,
* [(16.4.2)](#16.4.2)
a direct base class relationship (D, B) ([[class.derived.general]](class.derived.general "11.7.1General"))
for which either D or B is TU-local, or
* [(16.4.3)](#16.4.3)
a data member description (T, N, A, W, NUA) ([[class.mem.general]](class.mem.general "11.4.1General"))
for which T is TU-local[.](#16.sentence-1)
[17](#17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3272)
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*](module.private.frag#nt:private-module-fragment "10.5Private module fragment[module.private.frag]"), if any) or
module partition ([[module.unit]](module.unit "10.1Module units and purviews")) is an exposure,
the program is ill-formed[.](#17.sentence-1)
Such a declaration in any other context is deprecated ([[depr.local]](depr.local "D.2Non-local use of TU-local entities"))[.](#17.sentence-2)
[18](#18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3280)
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[.](#18.sentence-1)
A declaration instantiated for a template specialization ([[temp.spec]](temp.spec "13.9Template instantiation and specialization"))
appears at the point of instantiation of the specialization ([[temp.point]](temp.point "13.8.4.1Point of instantiation"))[.](#18.sentence-2)
[19](#19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3288)
[*Example [4](#example-4)*:
Translation unit #1:export module A;static void f() {}inline void it() { f(); } // error: is an exposure of fstatic inline void its() { f(); } // OKtemplate<int> void g() { its(); } // OKtemplate void g<0>();
decltype(f) *fp; // error: f (though not its type) is TU-localauto &fr = f; // OKconstexpr auto &fr2 = fr; // error: is an exposure of fconstexpr static auto fp2 = fr; // OKstruct S { void (&ref)(); } s{f}; // OK, value is TU-localconstexpr extern struct W { S &s; } wrap{s}; // OK, value is not TU-localstatic auto x = []{f();}; // OKauto x2 = x; // error: the closure type is TU-localint y = ([]{f();}(),0); // error: the closure type is not TU-localint y2 = (x,0); // OKnamespace N {struct A {}; void adl(A); static void adl(int);}void adl(double);
inline void h(auto x) { adl(x); } // OK, but certain specializations are exposuresconstexpr std::meta::info r1 = ^^g<0>; // OKnamespace N2 {static constexpr std::meta::info r2 = ^^g<1>; // OK, r2 is TU-local}constexpr std::meta::info r3 = ^^f; // error: r3 is an exposure of fconstexpr auto ctx = std::meta::access_context::current();constexpr std::meta::info r4 = std::meta::members_of(^^N2, ctx)[0]; // error: r4 is an exposure of N2::r2
Translation unit #2:module A;void other() { g<0>(); // OK, specialization is explicitly instantiated g<1>(); // error: instantiation uses TU-local its h(N::A{}); // error: overload set contains TU-local N::adl(int) h(0); // OK, calls adl(double) adl(N::A{}); // OK; N::adl(int) not found, calls N::adl(N::A) fr(); // OK, calls fconstexpr auto ptr = fr; // error: fr is not usable in constant expressions here} — *end example*]