[module.global.frag] # 10 Modules [[module]](./#module) ## 10.4 Global module fragment [module.global.frag] [global-module-fragment:](#nt:global-module-fragment "10.4 Global module fragment [module.global.frag]") module-keyword ; [*declaration-seq*](dcl.pre#nt:declaration-seq "9.1 Preamble [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.1 Preamble [dcl.pre]") ([[cpp.pre]](cpp.pre "15.1 Preamble"))[.](#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.4 Global module fragment [module.global.frag]") specifies the contents of the[*global module fragment*](#def:global_module_fragment "10.4 Global 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.4 Global 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.1 General [expr.prim.id.general]"),[*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1 General [namespace.def.general]"),[*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]"),[*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]") 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.3 One-definition rule")) appearing in S, or - [(3.3)](#3.3) S contains a dependent call E ([[temp.dep]](temp.dep "13.8.3 Dependent 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.3 Address 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.1 General [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.1 Preamble [dcl.pre]"),typedef declaration,[*using-declaration*](namespace.udecl#nt:using-declaration "9.10 The using declaration [namespace.udecl]"), or[*namespace-alias-definition*](namespace.alias#nt:namespace-alias-definition "9.9.3 Namespace 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.3 Names of template specializations [temp.names]") that does not denote a dependent type and whose [*template-name*](temp.names#nt:template-name "13.3 Names 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.6 Decltype 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.9 Expression splicing [expr.prim.splice]"), a [*splice-type-specifier*](dcl.type.splice#nt:splice-type-specifier "9.2.9.9 Type splicing [dcl.type.splice]"), a [*splice-scope-specifier*](expr.prim.id.qual#nt:splice-scope-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]"), or any [*splice-specifier*](basic.splice#nt:splice-specifier "6.6 Splice specifiers [basic.splice]") or[*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6 Splice 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.4 Global module fragment [module.global.frag]") if D is not decl-reachable from any [*declaration*](dcl.pre#nt:declaration "9.1 Preamble [dcl.pre]") in the [*declaration-seq*](dcl.pre#nt:declaration-seq "9.1 Preamble [dcl.pre]") of the [*translation-unit*](basic.link#nt:translation-unit "6.7 Program 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.1 Point of instantiation")) are outside the module unit, even when the instantiation context ([[module.context]](module.context "10.6 Instantiation 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 struct S;template struct S2;constexpr int g(int); template S> 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](#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 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)](#footnote-86)[86)](#footnoteref-86) A declaration can appear within a [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") in the initializer of a variable[.](#footnote-86.sentence-1)