[module.unit] # 10 Modules [[module]](./#module) ## 10.1 Module units and purviews [module.unit] [module-declaration:](#nt:module-declaration "10.1 Module units and purviews [module.unit]") export-keywordopt module-keyword [*module-name*](#nt:module-name "10.1 Module units and purviews [module.unit]") [*module-partition*](#nt:module-partition "10.1 Module units and purviews [module.unit]")opt [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt ; [module-name:](#nt:module-name "10.1 Module units and purviews [module.unit]") [*module-name-qualifier*](#nt:module-name-qualifier "10.1 Module units and purviews [module.unit]")opt [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") [module-partition:](#nt:module-partition "10.1 Module units and purviews [module.unit]") : [*module-name-qualifier*](#nt:module-name-qualifier "10.1 Module units and purviews [module.unit]")opt [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") [module-name-qualifier:](#nt:module-name-qualifier "10.1 Module units and purviews [module.unit]") [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") . [*module-name-qualifier*](#nt:module-name-qualifier "10.1 Module units and purviews [module.unit]") [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") . [1](#1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L29) A [*module unit*](#def:module_unit "10.1 Module units and purviews [module.unit]") is a translation unit that contains a [*module-declaration*](#nt:module-declaration "10.1 Module units and purviews [module.unit]")[.](#1.sentence-1) A [*named module*](#def:module,named "10.1 Module units and purviews [module.unit]") is the collection of module units with the same [*module-name*](#nt:module-name "10.1 Module units and purviews [module.unit]")[.](#1.sentence-2) The identifiers module and import shall not appear as [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")*s* in a [*module-name*](#nt:module-name "10.1 Module units and purviews [module.unit]") or [*module-partition*](#nt:module-partition "10.1 Module units and purviews [module.unit]")[.](#1.sentence-3) All [*module-name*](#nt:module-name "10.1 Module units and purviews [module.unit]")*s* either beginning with an [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") consisting of std followed by zero or more [*digit*](lex.name#nt:digit "5.11 Identifiers [lex.name]")*s* or containing a reserved identifier ([[lex.name]](lex.name "5.11 Identifiers")) are reserved and shall not be specified in a [*module-declaration*](#nt:module-declaration "10.1 Module units and purviews [module.unit]"); no diagnostic is required[.](#1.sentence-4) If any [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") in a reserved [*module-name*](#nt:module-name "10.1 Module units and purviews [module.unit]") is a reserved identifier, the module name is reserved for use by C++ implementations; otherwise it is reserved for future standardization[.](#1.sentence-5) The optional [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") appertains to the [*module-declaration*](#nt:module-declaration "10.1 Module units and purviews [module.unit]")[.](#1.sentence-6) [2](#2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L50) A [*module interface unit*](#def:module_interface_unit "10.1 Module units and purviews [module.unit]") is a module unit whose[*module-declaration*](#nt:module-declaration "10.1 Module units and purviews [module.unit]") starts with *export-keyword*; any other module unit is a [*module implementation unit*](#def:module_implementation_unit "10.1 Module units and purviews [module.unit]")[.](#2.sentence-1) A named module shall contain exactly one module interface unit with no [*module-partition*](#nt:module-partition "10.1 Module units and purviews [module.unit]"), known as the[*primary module interface unit*](#def:primary_module_interface_unit "10.1 Module units and purviews [module.unit]") of the module; no diagnostic is required[.](#2.sentence-2) [3](#3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L59) A [*module partition*](#def:module_partition "10.1 Module units and purviews [module.unit]") is a module unit whose [*module-declaration*](#nt:module-declaration "10.1 Module units and purviews [module.unit]") contains a [*module-partition*](#nt:module-partition "10.1 Module units and purviews [module.unit]")[.](#3.sentence-1) A named module shall not contain multiple module partitions with the same [*module-partition*](#nt:module-partition "10.1 Module units and purviews [module.unit]")[.](#3.sentence-2) All module partitions of a module that are module interface units shall be directly or indirectly exported by the primary module interface unit ([[module.import]](module.import "10.3 Import declaration"))[.](#3.sentence-3) No diagnostic is required for a violation of these rules[.](#3.sentence-4) [*Note [1](#note-1)*: Module partitions can be imported only by other module units in the same module[.](#3.sentence-5) The division of a module into module units is not visible outside the module[.](#3.sentence-6) — *end note*] [4](#4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L77) [*Example [1](#example-1)*: Translation unit #1:export module A;export import :Foo;export int baz(); Translation unit #2:export module A:Foo;import :Internals;export int foo() { return 2 * (bar() + 1); } Translation unit #3:module A:Internals;int bar(); Translation unit #4:module A;import :Internals;int bar() { return baz() - 10; }int baz() { return 30; } Module A contains four translation units: - [(4.1)](#4.1) a primary module interface unit, - [(4.2)](#4.2) a module partition A:Foo, which is a module interface unit forming part of the interface of module A, - [(4.3)](#4.3) a module partition A:Internals, which does not contribute to the external interface of module A, and - [(4.4)](#4.4) a module implementation unit providing a definition of bar and baz, which cannot be imported because it does not have a partition name[.](#4.sentence-1) — *end example*] [5](#5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L117) A [*module unit purview*](#def:purview,module_unit "10.1 Module units and purviews [module.unit]") is the sequence of [*token*](lex.token#nt:token "5.10 Tokens [lex.token]")*s* starting at the [*module-declaration*](#nt:module-declaration "10.1 Module units and purviews [module.unit]") and extending to the end of the translation unit[.](#5.sentence-1) The [*purview*](#def:purview,named_module "10.1 Module units and purviews [module.unit]") of a named module M is the set of module unit purviews of M's module units[.](#5.sentence-2) [6](#6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L126) The [*global module*](#def:module,global "10.1 Module units and purviews [module.unit]") is the collection of all[*global-module-fragment*](module.global.frag#nt:global-module-fragment "10.4 Global module fragment [module.global.frag]")*s* and all translation units that are not module units[.](#6.sentence-1) Declarations appearing in such a context are said to be in the [*purview*](#def:purview,global_module "10.1 Module units and purviews [module.unit]") of the global module[.](#6.sentence-2) [*Note [2](#note-2)*: The global module has no name, no module interface unit, and is not introduced by any [*module-declaration*](#nt:module-declaration "10.1 Module units and purviews [module.unit]")[.](#6.sentence-3) — *end note*] [7](#7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L137) A [*module*](#def:module "10.1 Module units and purviews [module.unit]") is either a named module or the global module[.](#7.sentence-1) A declaration is [*attached*](#def:attached,declaration "10.1 Module units and purviews [module.unit]") to a module as follows: - [(7.1)](#7.1) If the declaration is a non-dependent friend declaration that nominates a function with a [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") that is a [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") or [*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]") or that nominates a class other than with an [*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]") with neither a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") nor a [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]"), it is attached to the module to which the friend is attached ([[basic.link]](basic.link "6.7 Program and linkage"))[.](#7.1.sentence-1) - [(7.2)](#7.2) Otherwise, if the declaration * [(7.2.1)](#7.2.1) declares a namespace whose name has external linkage, * [(7.2.2)](#7.2.2) declares a type alias, * [(7.2.3)](#7.2.3) declares a namespace alias, or * [(7.2.4)](#7.2.4) appears within a [*linkage-specification*](dcl.link#nt:linkage-specification "9.12 Linkage specifications [dcl.link]") ([[dcl.link]](dcl.link "9.12 Linkage specifications")) it is attached to the global module[.](#7.2.sentence-1) - [(7.3)](#7.3) Otherwise, the declaration is attached to the module in whose purview it appears[.](#7.3.sentence-1) [8](#8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L162) A [*module-declaration*](#nt:module-declaration "10.1 Module units and purviews [module.unit]") that contains neither an *export-keyword* nor a [*module-partition*](#nt:module-partition "10.1 Module units and purviews [module.unit]") implicitly imports the primary module interface unit of the module as if by a [*module-import-declaration*](module.import#nt:module-import-declaration "10.3 Import declaration [module.import]")[.](#8.sentence-1) [*Example [2](#example-2)*: Translation unit #1:module B:Y; // does not implicitly import Bint y(); Translation unit #2:export module B;import :Y; // OK, does not create interface dependency cycleint n = y(); Translation unit #3:module B:X1; // does not implicitly import Bint &a = n; // error: n not visible here Translation unit #4:module B:X2; // does not implicitly import Bimport B;int &b = n; // OK Translation unit #5:module B; // implicitly imports Bint &c = n; // OK — *end example*]