[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<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.1 General [expr.prim.lambda.general]") in the initializer of a variable[.](#footnote-86.sentence-1)
