525 lines
22 KiB
Markdown
525 lines
22 KiB
Markdown
[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.7 Program and linkage [basic.link]") consists of one or more [translation units](lex.separate#def:translation_unit "5.1 Separate 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.7 Program and linkage [basic.link]")
|
||
[*declaration-seq*](dcl.pre#nt:declaration-seq "9.1 Preamble [dcl.pre]")opt
|
||
[*global-module-fragment*](module.global.frag#nt:global-module-fragment "10.4 Global module fragment [module.global.frag]")opt [*module-declaration*](module.unit#nt:module-declaration "10.1 Module units and purviews [module.unit]") [*declaration-seq*](dcl.pre#nt:declaration-seq "9.1 Preamble [dcl.pre]")opt [*private-module-fragment*](module.private.frag#nt:private-module-fragment "10.5 Private 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.7 Program and linkage [basic.link]"),[*module linkage*](#def:linkage,module "6.7 Program and linkage [basic.link]"),[*internal linkage*](#def:linkage,internal "6.7 Program and linkage [basic.link]"), or[*no linkage*](#def:linkage,no "6.7 Program 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.6 Namespace 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.5 Private 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.1 Preamble")), 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.4 The typedef specifier")); or
|
||
|
||
- [(4.4)](#4.4)
|
||
|
||
a named [enumeration](dcl.enum "9.8.1 Enumeration 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.4 The 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.1 Enumeration 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.2 Export declaration [module.interface]"),
|
||
the name has the same linkage, if any,
|
||
as the name of the enclosing class ([[class.friend]](class.friend "11.8.4 Friends"));
|
||
|
||
- [(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.1 Module units and purviews"))
|
||
and is not exported ([[module.interface]](module.interface "10.2 Export 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.4 The 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.3 Block 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.4 The typedef specifier"), [[dcl.enum]](dcl.enum "9.8.1 Enumeration declarations")),
|
||
they correspond ([[basic.scope.scope]](basic.scope.scope "6.4.1 General")),
|
||
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.12 Linkage specifications"), [[temp.type]](temp.type "13.6 Type equivalence"), [[temp.spec.partial]](temp.spec.partial "13.7.6 Partial 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.7 Program 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.5 Elaborated 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.1 Preamble [temp.pre]") ([[temp.over.link]](temp.over.link "13.7.7.2 Function 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.1 Preamble [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.1 Preamble [temp.pre]") and [*defining-type-id*](dcl.name#nt:defining-type-id "9.3.2 Type 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.4 The 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.5 Arrays"))[.](#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.12 Linkage specifications [dcl.link]") ([[dcl.link]](dcl.link "9.12 Linkage 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.7 Program 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.1 General [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.10 The reflection operator [expr.reflect]") or a [*splice-specifier*](basic.splice#nt:splice-specifier "6.6 Splice specifiers [basic.splice]") that, respectively, represents or designates E,
|
||
|
||
- [(13.3)](#13.3)
|
||
|
||
D is an injected declaration ([[expr.const]](expr.const "7.7 Constant 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.1 General"))
|
||
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.1 General [expr.prim.id.general]"),[*type-specifier*](dcl.type.general#nt:type-specifier "9.2.9.1 General [dcl.type.general]"),[*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]"),[*template-name*](temp.names#nt:template-name "13.3 Names of template specializations [temp.names]"), or[*concept-name*](temp.concept#nt:concept-name "13.7.9 Concept 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.3 One-definition rule")) or
|
||
an [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [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.8 Name 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.7 Program 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.1 General [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.7 Placeholder type specifiers"))),
|
||
|
||
- [(14.2)](#14.2)
|
||
|
||
the [*initializer*](dcl.init.general#nt:initializer "9.5.1 General [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.3 One-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.7 Program 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.1 General [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.1 Preamble [class.pre]"),
|
||
function body, or[*initializer*](dcl.init.general#nt:initializer "9.5.1 General [dcl.init.general]") or is introduced by a [*defining-type-specifier*](dcl.type.general#nt:defining-type-specifier "9.2.9.1 General [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.7 Program 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.2 Fundamental 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.1 General"))
|
||
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.1 General"))
|
||
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.5 Private module fragment [module.private.frag]"), if any) or
|
||
module partition ([[module.unit]](module.unit "10.1 Module 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.2 Non-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.9 Template instantiation and specialization"))
|
||
appears at the point of instantiation of the specialization ([[temp.point]](temp.point "13.8.4.1 Point 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*]
|