150 lines
8.1 KiB
Markdown
150 lines
8.1 KiB
Markdown
[module.interface]
|
||
|
||
# 10 Modules [[module]](./#module)
|
||
|
||
## 10.2 Export declaration [module.interface]
|
||
|
||
[export-declaration:](#nt:export-declaration "10.2 Export declaration [module.interface]")
|
||
export [*name-declaration*](dcl.pre#nt:name-declaration "9.1 Preamble [dcl.pre]")
|
||
export { [*declaration-seq*](dcl.pre#nt:declaration-seq "9.1 Preamble [dcl.pre]")opt }
|
||
export-keyword [*module-import-declaration*](module.import#nt:module-import-declaration "10.3 Import declaration [module.import]")
|
||
|
||
[1](#1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L206)
|
||
|
||
An [*export-declaration*](#nt:export-declaration "10.2 Export declaration [module.interface]") shall inhabit
|
||
a namespace scope and appear in the purview of a module interface unit[.](#1.sentence-1)
|
||
|
||
An [*export-declaration*](#nt:export-declaration "10.2 Export declaration [module.interface]") shall not appear directly
|
||
or indirectly within an unnamed namespace
|
||
or a [*private-module-fragment*](module.private.frag#nt:private-module-fragment "10.5 Private module fragment [module.private.frag]")[.](#1.sentence-2)
|
||
|
||
An [*export-declaration*](#nt:export-declaration "10.2 Export declaration [module.interface]") has the declarative effects of its[*name-declaration*](dcl.pre#nt:name-declaration "9.1 Preamble [dcl.pre]"),[*declaration-seq*](dcl.pre#nt:declaration-seq "9.1 Preamble [dcl.pre]") (if any), or[*module-import-declaration*](module.import#nt:module-import-declaration "10.3 Import declaration [module.import]")[.](#1.sentence-3)
|
||
|
||
The [*name-declaration*](dcl.pre#nt:name-declaration "9.1 Preamble [dcl.pre]") of an [*export-declaration*](#nt:export-declaration "10.2 Export declaration [module.interface]") shall not declare a partial specialization ([[temp.decls.general]](temp.decls.general "13.7.1 General"))[.](#1.sentence-4)
|
||
|
||
The [*declaration-seq*](dcl.pre#nt:declaration-seq "9.1 Preamble [dcl.pre]") of
|
||
an [*export-declaration*](#nt:export-declaration "10.2 Export declaration [module.interface]") shall not contain an [*export-declaration*](#nt:export-declaration "10.2 Export declaration [module.interface]") or[*module-import-declaration*](module.import#nt:module-import-declaration "10.3 Import declaration [module.import]")[.](#1.sentence-5)
|
||
|
||
[*Note [1](#note-1)*:
|
||
|
||
An [*export-declaration*](#nt:export-declaration "10.2 Export declaration [module.interface]") does not establish a scope[.](#1.sentence-6)
|
||
|
||
â *end note*]
|
||
|
||
[2](#2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L227)
|
||
|
||
A declaration is [*exported*](#def:declaration,exported "10.2 Export declaration [module.interface]") if it is
|
||
declared within an [*export-declaration*](#nt:export-declaration "10.2 Export declaration [module.interface]") and
|
||
inhabits a namespace scope or it is
|
||
|
||
- [(2.1)](#2.1)
|
||
|
||
a [*namespace-definition*](namespace.def.general#nt:namespace-definition "9.9.2.1 General [namespace.def.general]") that contains an
|
||
exported declaration, or
|
||
|
||
- [(2.2)](#2.2)
|
||
|
||
a declaration within a header unit ([[module.import]](module.import "10.3 Import declaration"))
|
||
that introduces at least one name[.](#2.sentence-1)
|
||
|
||
[3](#3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L238)
|
||
|
||
If an exported declaration is not within a header unit,
|
||
it shall not declare a name with internal linkage[.](#3.sentence-1)
|
||
|
||
[4](#4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L242)
|
||
|
||
[*Example [1](#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 unitexport module M;export namespace {} // error: namespace has internal linkagenamespace {export int a2; // error: export of name with internal linkage}export static int b; // error: b explicitly declared staticexport int f(); // OKexport namespace N { } // OKexport using namespace N; // OK â *end example*]
|
||
|
||
[5](#5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L264)
|
||
|
||
If an exported declaration is a [*using-declaration*](namespace.udecl#nt:using-declaration "9.10 The using declaration [namespace.udecl]") ([[namespace.udecl]](namespace.udecl "9.10 The using declaration"))
|
||
and is not within a header unit,
|
||
all entities named by the[*using-declarator*](namespace.udecl#nt:using-declarator "9.10 The using declaration [namespace.udecl]")*s* (if any)
|
||
shall either be a type alias or
|
||
have been introduced with a name having external linkage[.](#5.sentence-1)
|
||
|
||
[*Example [2](#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; // OKstruct S;export using ::S; // error: S has module linkagenamespace N {export int h(); static int h(int); // #1}export using N::h; // error: #1 has internal linkage â *end example*]
|
||
|
||
[*Note [2](#note-2)*:
|
||
|
||
The underlying entity of an exported type alias
|
||
need not have a name with external linkage[.](#5.sentence-2)
|
||
|
||
[*Example [3](#example-3)*: export module M;struct S;export using T = S; // OK, exports name T denoting type S â *end example*]
|
||
|
||
â *end note*]
|
||
|
||
[6](#6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L313)
|
||
|
||
A redeclaration of an entity X is implicitly exported
|
||
if X was introduced by an exported declaration;
|
||
otherwise it shall not be exported
|
||
unless it is a type alias, a namespace, or a namespace alias[.](#6.sentence-1)
|
||
|
||
[*Example [4](#example-4)*: export module M;struct S { int n; };typedef S S;export typedef S S; // OKexport struct S; // error: exported declaration follows non-exported declarationnamespace N { // external linkage, attached to global module, not exportedvoid f();}namespace N { // OK, exported namespace redeclaring non-exported namespaceexport void g();} â *end example*]
|
||
|
||
[7](#7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L335)
|
||
|
||
[*Note [3](#note-3)*:
|
||
|
||
Names introduced by exported declarations
|
||
have either external linkage or no linkage; see [[basic.link]](basic.link "6.7 Program and linkage")[.](#7.sentence-1)
|
||
|
||
Namespace-scope declarations exported by a module can be found by name lookup
|
||
in any translation unit importing that module ([[basic.lookup]](basic.lookup "6.5 Name lookup"))[.](#7.sentence-2)
|
||
|
||
Class and enumeration member names can be found by name lookup in any
|
||
context in which a definition of the type is reachable[.](#7.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[*Example [5](#example-5)*:
|
||
|
||
Interface unit of M:export module M;export struct X {static void f(); struct Y { };};
|
||
|
||
namespace {struct S { };}export void f(S); // OKstruct T { };export T id(T); // OKexport struct A; // A exported as incompleteexport 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 typeauto f = rootFinder(2); // OKreturn A{45}.value; // error: A is incomplete} â *end example*]
|
||
|
||
[8](#8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L386)
|
||
|
||
[*Note [4](#note-4)*:
|
||
|
||
Declarations in an exported [*namespace-definition*](namespace.def.general#nt:namespace-definition "9.9.2.1 General [namespace.def.general]") or in an exported [*linkage-specification*](dcl.link#nt:linkage-specification "9.12 Linkage specifications [dcl.link]") ([[dcl.link]](dcl.link "9.12 Linkage specifications"))
|
||
are exported and subject to the rules of exported declarations[.](#8.sentence-1)
|
||
|
||
[*Example [6](#example-6)*: export module M;int g;export namespace N {int x; // OKusing ::g; // error: ::g has module linkage} â *end example*]
|
||
|
||
â *end note*]
|