10 Modules [module]

10.2 Export declaration [module.interface]

An export-declaration shall inhabit a namespace scope and appear in the purview of a module interface unit.
An export-declaration shall not appear directly or indirectly within an unnamed namespace or a private-module-fragment.
An export-declaration has the declarative effects of its declaration, declaration-seq (if any), or module-import-declaration.
[Note 1:
An export-declaration does not establish a scope.
— end note]
A declaration is exported if it is declared within an export-declaration and inhabits a namespace scope or it is
An exported declaration that is not a module-import-declaration shall declare at least one name.
If the declaration is not within a header unit, it shall not declare a name with internal linkage.
[Example 1:

Source file "a.h":export int x;

Translation unit #1:module; #include "a.h" // error: declaration of x is not in the // purview of a module interface unit export module M; export namespace {} // error: does not introduce any names export namespace { int a1; // error: export of name with internal linkage } namespace { export int a2; // error: export of name with internal linkage } export static int b; // error: b explicitly declared static export int f(); // OK export namespace N { } // OK export using namespace N; // error: does not declare a name — end example]

If the declaration is a using-declaration ([namespace.udecl]) and is not within a header unit, all entities to which all of the using-declarators ultimately refer (if any) shall have been introduced with a name having external linkage.
[Example 2:

Source file "b.h":int f();

Importable header "c.h":int g();

Translation unit #1:export module X; export int h();

Translation unit #2:module; #include "b.h" export module M; import "c.h"; import X; export using ::f, ::g, ::h; // OK struct S; export using ::S; // error: S has module linkage namespace N { export int h(); static int h(int); // #1 } export using N::h; // error: #1 has internal linkage — end example]

[Note 2:
These constraints do not apply to type names introduced by typedef declarations and alias-declarations.
[Example 3: export module M; struct S; export using T = S; // OK, exports name T denoting type S — end example]
— end note]
A redeclaration of an entity X is implicitly exported if X was introduced by an exported declaration; otherwise it shall not be exported.
[Example 4: export module M; struct S { int n; }; typedef S S; export typedef S S; // OK, does not redeclare an entity export struct S; // error: exported declaration follows non-exported declaration — end example]
[Note 3:
Names introduced by exported declarations have either external linkage or no linkage; see [basic.link].
Namespace-scope declarations exported by a module can be found by name lookup in any translation unit importing that module ([basic.lookup]).
Class and enumeration member names can be found by name lookup in any context in which a definition of the type is reachable.
— end note]
[Example 5:

Interface unit of M:export module M; export struct X { static void f(); struct Y { }; }; namespace { struct S { }; } export void f(S); // OK struct T { }; export T id(T); // OK export struct A; // A exported as incomplete export auto rootFinder(double a) { return [=](double x) { return (x + a/x)/2; }; } export const int n = 5; // OK, n has external linkage

Implementation unit of M:module M; struct A { int value; };

Main program:import M; int main() { X::f(); // OK, X is exported and definition of X is reachable X::Y y; // OK, X​::​Y is exported as a complete type auto f = rootFinder(2); // OK return A{45}.value; // error: A is incomplete } — end example]

[Note 4:
Declarations in an exported namespace-definition or in an exported linkage-specification ([dcl.link]) are exported and subject to the rules of exported declarations.
[Example 6: export module M; export namespace N { int x; // OK static_assert(1 == 1); // error: does not declare a name } — end example]
— end note]