[module.interface] (original) (raw)

10 Modules [module]

10.2 Export declaration [module.interface]

An export-declaration shall appear only at namespace scope and only 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.

A declaration is exported if it is

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" export module M;export namespace {} export namespace { int a1; } namespace { export int a2; } export static int b; export int f(); export namespace N { } export using namespace N; — _end example_]

If the declaration is a using-declaration ([namespace.udecl]) and is not within a header unit, all entities to which all of theusing-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; struct S;export using ::S; namespace N { export int h();static int h(int); } export using N::h; — _end example_]

[Note 1:

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; — _end example_]

— _end note_]

A redeclaration of an exported declaration of an entity is implicitly exported.

An exported redeclaration of a non-exported declaration of an entity is ill-formed.

[Example 4: export module M;struct S { int n; };typedef S S;export typedef S S; export struct S; — _end example_]

A name is exported by a module if it is introduced or redeclared by an exported declaration in the purview of that module.

[Note 2:

Exported names have either external linkage or no linkage; see [basic.link].

Namespace-scope names exported by a module are visible to name lookup in any translation unit importing that module; see [basic.scope.namespace].

Class and enumeration member names are visible to 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); struct T { };export T id(T); export struct A; export auto rootFinder(double a) { return [=](double x) { return (x + a/x)/2; };} export const int n = 5;

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

Main program:import M;int main() { X::f(); X::Y y; auto f = rootFinder(2); return A{45}.value; } — _end example_]

[Note 3:

Redeclaring a name in an export-declarationcannot change the linkage of the name ([basic.link]).

[Example 6:

Interface unit of M:export module M;static int f(); export int f(); struct S; export struct S; namespace { namespace N { extern int x; } } export int N::x; — _end example_]

— _end note_]

[Note 4:

[Example 7: export module M;export namespace N { int x; static_assert(1 == 1); } — _end example_]

— _end note_]