10 Modules [module]

10.1 Module units and purviews [module.unit]

module-declaration:
export-keyword module-keyword module-name module-partition attribute-specifier-seq ;
module-name:
module-name-qualifier identifier
module-partition:
: module-name-qualifier identifier
module-name-qualifier:
identifier .
module-name-qualifier identifier .
A module unit is a translation unit that contains a module-declaration.
A named module is the collection of module units with the same module-name.
The identifiers module and import shall not appear as identifiers in a module-name or module-partition.
All module-names either beginning with an identifier consisting of std followed by zero or more digits or containing a reserved identifier ([lex.name]) are reserved and shall not be specified in a module-declaration; no diagnostic is required.
If any identifier in a reserved module-name is a reserved identifier, the module name is reserved for use by C++ implementations; otherwise it is reserved for future standardization.
The optional attribute-specifier-seq appertains to the module-declaration.
A module interface unit is a module unit whose module-declaration starts with export-keyword; any other module unit is a module implementation unit.
A named module shall contain exactly one module interface unit with no module-partition, known as the primary module interface unit of the module; no diagnostic is required.
A module partition is a module unit whose module-declaration contains a module-partition.
A named module shall not contain multiple module partitions with the same module-partition.
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]).
No diagnostic is required for a violation of these rules.
[Note
:
Module partitions can be imported only by other module units in the same module.
The division of a module into module units is not visible outside the module.
— end note
]
[Example
:

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:
  • a primary module interface unit,
  • a module partition A:Foo, which is a module interface unit forming part of the interface of module A,
  • a module partition A:Internals, which does not contribute to the external interface of module A, and
  • a module implementation unit providing a definition of bar and baz, which cannot be imported because it does not have a partition name.
— end example
]
A module unit purview is the sequence of tokens starting at the module-declaration and extending to the end of the translation unit.
The purview of a named module M is the set of module unit purviews of M's module units.
The global module is the collection of all global-module-fragments and all translation units that are not module units.
Declarations appearing in such a context are said to be in the purview of the global module.
[Note
:
The global module has no name, no module interface unit, and is not introduced by any module-declaration.
— end note
]
A module is either a named module or the global module.
A declaration is attached to a module as follows:
A module-declaration that contains neither an export-keyword nor a module-partition implicitly imports the primary module interface unit of the module as if by a module-import-declaration.
[Example
:

Translation unit #1:

module B:Y;                     // does not implicitly import B
int y();

Translation unit #2:

export module B;
import :Y;                      // OK, does not create interface dependency cycle
int n = y();

Translation unit #3:

module B:X1;                    // does not implicitly import B
int &a = n;                     // error: n not visible here

Translation unit #4:

module B:X2;                    // does not implicitly import B
import B;
int &b = n;                     // OK

Translation unit #5:

module B;                       // implicitly imports B
int &c = n;                     // OK
— end example
]