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

190 lines
9.8 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.

[module.global.frag]
# 10 Modules [[module]](./#module)
## 10.4 Global module fragment [module.global.frag]
[global-module-fragment:](#nt:global-module-fragment "10.4Global module fragment[module.global.frag]")
module-keyword ; [*declaration-seq*](dcl.pre#nt:declaration-seq "9.1Preamble[dcl.pre]")opt
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L590)
[*Note [1](#note-1)*:
Prior to phase 4 of translation,
only preprocessing directives can appear
in the [*declaration-seq*](dcl.pre#nt:declaration-seq "9.1Preamble[dcl.pre]") ([[cpp.pre]](cpp.pre "15.1Preamble"))[.](#1.sentence-1)
— *end note*]
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L597)
A [*global-module-fragment*](#nt:global-module-fragment "10.4Global module fragment[module.global.frag]") specifies the contents of the[*global module fragment*](#def:global_module_fragment "10.4Global module fragment[module.global.frag]") for a module unit[.](#2.sentence-1)
The global module fragment can be used to provide declarations
that are attached to the global module and usable within the module unit[.](#2.sentence-2)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L603)
A declaration D is [*decl-reachable*](#def:decl-reachable "10.4Global module fragment[module.global.frag]") from a declaration S in the same translation unit if
- [(3.1)](#3.1)
D does not declare a function or function template andS contains an[*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]"),[*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1General[namespace.def.general]"),[*type-name*](dcl.type.simple#nt:type-name "9.2.9.3Simple type specifiers[dcl.type.simple]"),[*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]") naming D, or
- [(3.2)](#3.2)
D declares a function or function template that
is named by an expression ([[basic.def.odr]](basic.def.odr "6.3One-definition rule"))
appearing in S, or
- [(3.3)](#3.3)
S contains a dependent call E ([[temp.dep]](temp.dep "13.8.3Dependent names"))
and D is found by any name lookup performed
for an expression synthesized from E by replacing each type-dependent argument or operand
with a value of a placeholder type
with no associated namespaces or entities, or
[*Note [2](#note-2)*:
This includes the lookup for operator== performed
when considering rewriting an != expression,
the lookup for operator<=> performed when considering rewriting a relational comparison, and
the lookup for operator!= when considering whether an operator== is a rewrite target[.](#3.3.sentence-1)
— *end note*]
- [(3.4)](#3.4)
S contains an expression that
takes the address of an overload set ([[over.over]](over.over "12.3Address of an overload set"))
that contains D and
for which the target type is dependent, or
- [(3.5)](#3.5)
there exists a declaration M that is not a [*namespace-definition*](namespace.def.general#nt:namespace-definition "9.9.2.1General[namespace.def.general]") for which M is decl-reachable from S and either
* [(3.5.1)](#3.5.1)
D is decl-reachable from M, or
* [(3.5.2)](#3.5.2)
D and M declare the same entity,
and D neither is a friend declaration
nor inhabits a block scope, or
* [(3.5.3)](#3.5.3)
D declares a namespace N and M is a member of N, or
* [(3.5.4)](#3.5.4)
one of D and M declares a class or class template C and the other declares a member or friend of C, or
* [(3.5.5)](#3.5.5)
one of D and M declares an enumeration E and the other declares an enumerator of E, or
* [(3.5.6)](#3.5.6)
D declares a function or variable and M is declared in D,[86](#footnote-86 "A declaration can appear within a lambda-expression in the initializer of a variable.") or
* [(3.5.7)](#3.5.7)
one of D and M declares a template and the other declares
a partial or explicit specialization or
an implicit or explicit instantiation of that template, or
* [(3.5.8)](#3.5.8)
M declares a class template
and D is a deduction guide for that template, or
* [(3.5.9)](#3.5.9)
one of D and M declares a class or enumeration type
and the other introduces a typedef name for linkage purposes for that type[.](#3.sentence-1)
In this determination, it is unspecified
- [(3.6)](#3.6)
whether a reference to an[*alias-declaration*](dcl.pre#nt:alias-declaration "9.1Preamble[dcl.pre]"),typedef declaration,[*using-declaration*](namespace.udecl#nt:using-declaration "9.10The using declaration[namespace.udecl]"), or[*namespace-alias-definition*](namespace.alias#nt:namespace-alias-definition "9.9.3Namespace alias[namespace.alias]") is replaced by the declarations they name
prior to this determination,
- [(3.7)](#3.7)
whether a [*simple-template-id*](temp.names#nt:simple-template-id "13.3Names of template specializations[temp.names]") that does not denote a dependent type
and whose [*template-name*](temp.names#nt:template-name "13.3Names of template specializations[temp.names]") names an alias template
is replaced by its denoted type
prior to this determination,
- [(3.8)](#3.8)
whether a [*decltype-specifier*](dcl.type.decltype#nt:decltype-specifier "9.2.9.6Decltype specifiers[dcl.type.decltype]") that does not denote a dependent type
is replaced by its denoted type
prior to this determination,
- [(3.9)](#3.9)
whether a non-value-dependent constant expression
is replaced by the result of constant evaluation
prior to this determination,
and
- [(3.10)](#3.10)
whether
a [*splice-expression*](expr.prim.splice#nt:splice-expression "7.5.9Expression splicing[expr.prim.splice]"),
a [*splice-type-specifier*](dcl.type.splice#nt:splice-type-specifier "9.2.9.9Type splicing[dcl.type.splice]"),
a [*splice-scope-specifier*](expr.prim.id.qual#nt:splice-scope-specifier "7.5.5.3Qualified names[expr.prim.id.qual]"), or
any [*splice-specifier*](basic.splice#nt:splice-specifier "6.6Splice specifiers[basic.splice]") or[*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6Splice specifiers[basic.splice]") outside of the preceding is replaced in any non-dependent context
by the construct that it designates prior to this determination[.](#3.sentence-2)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L722)
A declaration D in a global module fragment of a module unit
is [*discarded*](#def:discarded,declaration "10.4Global module fragment[module.global.frag]") if D is not decl-reachable from any [*declaration*](dcl.pre#nt:declaration "9.1Preamble[dcl.pre]") in the [*declaration-seq*](dcl.pre#nt:declaration-seq "9.1Preamble[dcl.pre]") of the [*translation-unit*](basic.link#nt:translation-unit "6.7Program and linkage[basic.link]")[.](#4.sentence-1)
[*Note [3](#note-3)*:
A discarded declaration is neither reachable
nor visible to name lookup outside the module unit,
nor in template instantiations whose points of instantiation ([[temp.point]](temp.point "13.8.4.1Point of instantiation"))
are outside the module unit,
even when the instantiation context ([[module.context]](module.context "10.6Instantiation context"))
includes the module unit[.](#4.sentence-2)
— *end note*]
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L737)
[*Example [1](#example-1)*: const int size = 2;int ary1[size]; // unspecified whether size is decl-reachable from ary1constexpr int identity(int x) { return x; }int ary2[identity(2)]; // unspecified whether identity is decl-reachable from ary2template<typename> struct S;template<typename, int> struct S2;constexpr int g(int);
template<typename T, int N> S<S2<T, g(N)>> f(); // S, S2, g, and :: are decl-reachable from ftemplate<int N>void h() noexcept(g(N) == N); // g and :: are decl-reachable from h — *end example*]
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L757)
[*Example [2](#example-2)*:
Source file "foo.h":namespace N {struct X {}; int d(); int e(); inline int f(X, int = d()) { return e(); }int g(X); int h(X);}
Module M interface:module;#include "foo.h"export module M;template<typename T> int use_f() { N::X x; // N::X, N, and :: are decl-reachable from use_freturn f(x, 123); // N::f is decl-reachable from use_f,// N::e is indirectly decl-reachable from use_f// because it is decl-reachable from N::f, and// N::d is decl-reachable from use_f// because it is decl-reachable from N::f// even though it is not used in this call}template<typename T> int use_g() { N::X x; // N::X, N, and :: are decl-reachable from use_greturn g((T(), x)); // N::g is not decl-reachable from use_g}template<typename T> int use_h() { N::X x; // N::X, N, and :: are decl-reachable from use_hreturn h((T(), x)); // N::h is not decl-reachable from use_h, but// N::h is decl-reachable from use_h<int>}int k = use_h<int>(); // use_h<int> is decl-reachable from k, so// N::h is decl-reachable from k
Module M implementation:module M;int a = use_f<int>(); // OKint b = use_g<int>(); // error: no viable function for call to g;// g is not decl-reachable from purview of// module M's interface, so is discardedint c = use_h<int>(); // OK — *end example*]
[86)](#footnote-86)[86)](#footnoteref-86)
A declaration can appear within a [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1General[expr.prim.lambda.general]") in the initializer of a variable[.](#footnote-86.sentence-1)