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

9.8 KiB
Raw Permalink Blame History

[module.global.frag]

10 Modules [module]

10.4 Global module fragment [module.global.frag]

global-module-fragment:
module-keyword ; declaration-seqopt

1

#

[Note 1:

Prior to phase 4 of translation, only preprocessing directives can appear in the declaration-seq ([cpp.pre]).

— end note]

2

#

A global-module-fragment specifies the contents of theglobal module fragment for a module unit.

The global module fragment can be used to provide declarations that are attached to the global module and usable within the module unit.

3

#

A declaration D is decl-reachable from a declaration S in the same translation unit if

D does not declare a function or function template andS contains anid-expression,namespace-name,type-name,template-name, orconcept-name naming D, or

D declares a function or function template that is named by an expression ([basic.def.odr]) appearing in S, or

S contains a dependent call E ([temp.dep]) 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: 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. — end note]

S contains an expression that takes the address of an overload set ([over.over]) that contains D and for which the target type is dependent, or

there exists a declaration M that is not a namespace-definition for which M is decl-reachable from S and either

D is decl-reachable from M, or

D and M declare the same entity, and D neither is a friend declaration nor inhabits a block scope, or

D declares a namespace N and M is a member of N, or

one of D and M declares a class or class template C and the other declares a member or friend of C, or

one of D and M declares an enumeration E and the other declares an enumerator of E, or

D declares a function or variable and M is declared in D,86 or

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

M declares a class template and D is a deduction guide for that template, or

one of D and M declares a class or enumeration type and the other introduces a typedef name for linkage purposes for that type.

In this determination, it is unspecified

whether a reference to analias-declaration,typedef declaration,using-declaration, ornamespace-alias-definition is replaced by the declarations they name prior to this determination,

whether a simple-template-id that does not denote a dependent type and whose template-name names an alias template is replaced by its denoted type prior to this determination,

whether a decltype-specifier that does not denote a dependent type is replaced by its denoted type prior to this determination,

whether a non-value-dependent constant expression is replaced by the result of constant evaluation prior to this determination, and

whether a splice-expression, a splice-type-specifier, a splice-scope-specifier, or any splice-specifier orsplice-specialization-specifier outside of the preceding is replaced in any non-dependent context by the construct that it designates prior to this determination.

4

#

A declaration D in a global module fragment of a module unit is discarded if D is not decl-reachable from any declaration in the declaration-seq of the translation-unit.

[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]) are outside the module unit, even when the instantiation context ([module.context]) includes the module unit.

— end note]

5

#

[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 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 ftemplatevoid h() noexcept(g(N) == N); // g and :: are decl-reachable from h — end example]

6

#

[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 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 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 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 k = use_h(); // use_h is decl-reachable from k, so// N::h is decl-reachable from k

Module M implementation:module M;int a = use_f(); // OKint b = use_g(); // 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(); // OK — end example]

86)86)

A declaration can appear within a lambda-expression in the initializer of a variable.