Skip to content

Latest commit

 

History

History
329 lines (234 loc) · 20.8 KB

File metadata and controls

329 lines (234 loc) · 20.8 KB
description

Programming Languages — Extensions to C++ for Modules

5 Lexical Conventions

5.11 Keywords

In 5.11, add these two keywords to Table 3 in paragraph 5.11/1: module and import.

在5.11中为段落5.11/1的Table 3添加两个关键字:moduleimport

6 Basic concepts

3 An entity is a value, object, reference, function, enumerator, type, class member, bit-field, template, template specialization, namespace, module, parameter pack, or this.
3 实体是一个值、对象、引用、函数、枚举、类型、类成员、位字段、模板、模板特化、命名空间、模块、参数包或 this。

4 A name is a use of an identifier (5.10), operator-function-id (16.5), literal-operator-id (16.5.8), conversion-function-id (15.3.2), or template-id (17.2), or module-name (10.7) that denotes an entity or label (9.6.4, 9.1).– they are module-names composed of the same dotted sequence of identifiers.

– they are module-names composed of the same dotted sequence of identifiers.
– 模块名称由相似的由点分隔的标识符序列组成的。

6.1 Declarations and definitions

import std.io; // make names from std.io available
export module M; // declare module M
export struct Point { // define and export Point
    int x;
    int y;
};

6.2 One-definition rule

(3.2) of paragraph 6.5/3:

– a non-inline non-exported variable of non-volatile const-qualified type that is neither explicitly declared extern nor previously declared to have external linkage; or
– 一个非内联的非导出的non-volatile const-qualified type的变量,既没有被显式声明为extern,也没有被预先声明具有外部链接;或

6.5 Program and linkage

3 A name having namespace scope (6.3.6) has internal linkage if it is the name of

  • (3.1) — a variable, function or function template that is explicitly declared static; or,
  • (3.2) — a non-inline variable of non-volatile const-qualified type that is neither explicitly declared extern nor previously declared to have external linkage; or
  • (3.3) — a data member of an anonymous union.

7th to 6.2/6:

– if a declaration of D that is not a proclaimed-ownership-declaration appears in the purview of a module (10.7), all other such declarations shall appear in the purview of the same module and there can be at most one definition of D in the owning module.
– 如果一个非proclaimed-ownership-declaration(宣告所有权声明)的D的声明出现在模块的范围内(10.7),则所有其他此类声明都应出现在同一模块的范围内,且在模块内只能最多有一个D的定义。

There can be more than one definition of a class type (Clause 12), enumeration type (10.2), inline function with external linkage (10.1.6), inline variable with external linkage (10.1.6), class template (Clause 17), non-static function template (17.5.6), static data member of a class template (17.5.1.3), member function of a class template (17.5.1.1), or template specialization for which some template parameters are not specified (17.7, 17.5.5) in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements. Given such an entity named D defined in more than one translation unit, then

在一个程序中,如果每个定义出现在不同的编译单元中,并且定义满足后面列出的要求,则允许有一个以上的类定义(条款12),枚举类型(10.2),具有外部链接的内联函数(10.1.6),具有外部链接的内联变量(10.1.6),类模板(条款17),非静态函数模板(17.5.6),类模板静态数据成员(17.5.1.3),类模板成员函数(17.5.1.1),或偏特化的模板(17.7,17.5.5)。那么,给定一个在多个翻译单元中定义的名为D的实体

The purpose of this requirement is to implement module ownership of declarations.
这里的用意是实现模块所有权声明。

6.3 Scope

6.3.2 Point of declaration

6.3.2/13:

13 The point of declaration of a module is immediately after the module-name in a module-declaration.
13 模块的声明点紧跟在模块声明中的模块名之后。

The point of declaration for a name is immediately after its complete declarator (Clause 11) and before its initializer (if any)
一个名称的声明点紧跟在它的完整声明(条款11)之后,和它的初始化器之前(如果有)

6.3.6 Namespace scope

From end-user perspective, there are really no new lookup rules to learn. The “old” rules are the “new” rules, with appropriate adjustment in the definition of “associated entities.”
从最终用户的角度来看,实际上没有新的查找规则需要学习。“旧”规则就是“新”规则,在“associated entities”的定义上有适当的调整。

6.3.6/1:

If the name X of a namespace member is declared in a namespace-definition of a namespace N in the module interface unit of a module M, the potential scope of X includes the namespace-definitions of N in every module unit of M and, if the name X is exported, in every translation unit that imports M. [Example:
如果一个命名空间成员X声明在模块M的模块接口单元内的命名空间N中,那么X的潜在作用域包括了在每个M的模块单元,并且如果名称X是导出的,那么也包括了在每个导入了M的编译单元的N的命名空间定义范围。[ 例:

// Translation unit #1
export module M;
export int sq(int i) { return i*i; }

// Translation #2
import M;
int main() { return sq(9); } // OK: ’sq’ from module M

6.4 Name lookup

6.4.2 Argument-dependent name lookup

6.4.2/2:

// Header file X.h
namespace Q {
    struct X { };
}

// Interface unit of M1
#include "H.h" // global module
namespace Q {
    void g_impl(X, X);
}
export module M1;
export template<typename T>
void g1(T t) {
    g_impl(t, Q::X{ }); // #1
}
export template<typename T>
void g2(T t) {
    using Q::g_impl;
    g_impl(t, Q::X{ }); // #2
}
void j(Q::X x) {
    g1(x); // OK: g_impl found at #1
    g2(x); // OK: g_impl found at #2
}

// Interface unit of M2
#include "X.h"
import M1;
export module M2;
void h(Q::X x) {
    g1(x); // ill-formed: g_impl not found at #1
    g2(x); // OK: g_impl found at #2
}

6.5 Program and linkage

between 1st & 2nd of 6.5/2:

— When a name has module linkage, the entity it denotes is owned by a module M and can be referred to by name from other scopes of the same module unit (10.7) or from scopes of other module units of M.
****— 当名称具有模块链接时,它指明实体属于模块M,可以通过名称从同模块单元(10.7)的其他作用域或M的其他模块单元的作用域中引用。

6.5/6:

The name of a function declared in block scope and the name of a variable declared by a block scope extern declaration have linkage. If there is a visible declaration of an entity with linkage having the same name and type, ignoring entities declared outside the innermost enclosing namespace scope, the block scope declaration declares that same entity and receives the linkage of the previous declaration. If that entity was exported by an imported module, the program is ill-formed. If there is more than one such matching entity, the program is ill-formed. Otherwise, if no matching entity is found, the block scope entity receives external linkage and is owned by the global module.
块作用域中声明的函数名和块作用域外部声明的变量名具有链接属性。如果存在具有相同名称和类型的链接的实体的可见声明,而忽略了在最内部的封闭命名空间作用域范围之外声明的实体,块作用域声明就会声明该相同的实体并接收上一个声明的链接。如果该实体是由某个导入的模块导出的,则程序ill-formed。如果有多于一个这样的匹配实体,程序ill-formed。否则,如果没有找到匹配的实体,块作用域实体就会接收由全局模块所有的外部链接。

before 6.5/8:

A name declared at namespace scope in the purview of a module that does not have internal linkage by the previous rules and that is introduced by a non-exported declaration (10.7.1) has module linkage. The name of any class member where the enclosing class has a name with module linkage also has module linkage**.**
在一个模块的范围中,一个在命名空间作用域内声明的名称,不具有之前规则所示的内部链接,若它是由非导出声明(10.7.1)引入的,则具有模块链接。当外围类具有模块链接时,其任意一个类成员名称也将具有模块链接。

10 Declarations

10/1:

    export-declaration
    module-import-declaration

export-declaration :
    export declaration
    export { declaration-seq_{opt} }

module-import-declaration :
    import module-name attribute-specifier-seq_{opt} ;

10.1 Specifiers

10.1.2 Function specifiers

10.1.2/7:

7 An exported inline function shall be defined in the same translation unit containing its export declaration. An exported inline function has the same address in each translation unit importing its owning module. [ Note: There is no restriction on the linkage (or absence thereof) of entities that the function body of an exported inline function can reference. A constexpr function is implicitly inline. — end note ]
7 导出内联函数应在包含其导出声明的同一编译单元中定义。导出的内联函数在每个导入其所属模块的编译单元中具有相同的地址。[ 注:这里对导出内联函数的函数体能够引用的实体的链接(或者无链接)没有约束。一个constexpr函数是隐式内联的。]

10.3 Namespaces

10.3/1:

A namespace with external linkage is always exported regardless of whether any of its namespace-definitions is introduced by export. [ Note: There is no way to define a namespace with module linkage. — end note ][Example:
带有外部链接的命名空间总是被导出,而不管它的名称空间定义是否export。[ 注: 没有办法定义一个模块链接的命名空间。][ 例:

export module M;
namespace N { // N has external linkage and is exported
}

10.7 Modules

1 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. A translation unit may not contain more than one module-declaration. A module-name has external linkage but cannot be found by name lookup.
1 模块单元是包含了模块声明的翻译单元。具名模块是具有相同模块名称的模块单元的集合。一个编译单元不能包含一个以上的模块声明。模块名具有外部链接,但无法通过名称查找(name lookup)找到。

2 A module interface unit is a module unit whose module-declaration contains the export keyword; any other module unit is a module implementation unit. A named module shall contain exactly one module interface unit.
2 模块接口单元是一个在模块声明中包含了export关键字的模块单元;其它任何模块单元都是模块实现单元。一个具名模块应且仅应包含一个模块接口单元。

3 A module unit purview starts at the module-declaration and extends 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.
3 一个模块单元的范围由模块声明开始,一直到当前编译单元的尾部。具名模块M的范围是M的所有模块单元的模块单元范围的集合。

4 A namespace-scope declaration D of an entity (other than a module) in the purview of a module M is said to be owned by M. Equivalently, the module M is the owning module of D.
4 在模块M范围内的一个实体(模块除外)的命名空间作用域声明DM所有。相当于模块MD的持有模块。

5 The global module is the collection of all declarations not in the purview of any module-declaration. By extension, such declarations 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 ]
5 全局模块是所有不属于任何模块声明范围的声明的集合。推而广之,这些声明被认为属于全局模块的范围。[ 注:全局模块没有名称,没有模块接口单元,也不需要引入任何模块声明。]

6 A module is either a named module or the global module.
6 一个模块可以是具名模块或全局模块。

10.7.1 Export declaration 导出声明

1 An export-declaration shall only appear in the purview of a module unit. An export-declaration does not establish a scope and shall not contain more than one export keyword. The interface of a module M is the set of all export-declarations in its purview. An export-declaration of the form
导出声明只应出现在模块单元的范围内。导出声明没有规定范围,并且不能包含一个以上的export关键字。模块M的接口是其范围内所有导出声明的集合。一个导出声明形如

export declaration

shall declare at least one entity. The names of all entities in the interface of a module are visible to any translation unit importing that module. All entities with linkage other than internal linkage declared in the purview of the module interface unit of a module M are visible in the purview of all module implementation units of M. The entity and the declaration introduced by an export-declaration are said to be exported.
应声明至少一个实体。在一个模块接口中的所有实体的名称都对任意导入了此模块的编译单元可见。在模块M的模块接口单元范围中声明的所有带有链接(除内部链接之外)的实体,都在所有M的模块实现单元范围内可见。由一个导出声明(export-declaration)引入的实体和声明被称为导出的。

2 Every name introduced by an export-declaration shall have external linkage. If that declaration introduces an entity with a non-dependent type, then that type shall have external linkage or shall involve only types with external linkage. [Example:
每一个由导出声明(export-declaration)引入的名称都应该具有外部链接。如果该声明引入了具有非依赖类型(non-dependent type)的实体,则该类型应具有外部链接或仅涉及具有外部链接的类型。[ 例:

export module M;
export static int n = 43; // error: n has internal linkage
namespace {
    struct S { };
}
export void f(S); // error: parameter type has internal linkage
struct T { };
export T id(T); // OK

3 If an export-declaration introduces a namespace-definition, then each member of the corresponding namespace-body is implicitly exported and subject to the rules of export declarations.
如果导出声明引入了命名空间定义(namespace-definition),那么相应命名空间主体(namespace-body)的每个成员都隐式导出,并受导出声明规则的约束。

10.7.2 Import declaration 导入声明

1 A module-import-declaration shall appear only at global scope. A module-import-declaration makes exported declarations from the interface of the nominated module visible to name lookup in the current translation unit, in the same namespaces and contexts as in the nominated module. [ Note: The entities are not redeclared in the translation unit containing the module-import-declaration. — end note ] [ Example:
一个模块导入声明(module-import-declaration)只能出现在全局作用域中。模块导入声明使从指定模块接口中导出的声明可见,以便在当前编译单元中进行名称查找(name lookup),其命名空间和上下文与指定模块相同。[ 注:在包含模块导入声明的编译单元中,实体无需重新声明(redeclared)。] [ 例:

// Interface unit of M
export module M;
export namespace N {
    struct A { };
}
namespace N {
    struct B { };
    export struct C {
        friend void f(C) { } // exported, visible only through argument-dependent lookup
    };
}

// Translation unit 2
import M;
N::A a { }; // OK.
N::B b { }; // error: ‘B’ not found in N.
void h(N::C c) {
    f(c); // OK: ‘N::f’ found via argument-dependent lookup
    N::f(c); // error: ‘f’ not found via qualified lookup in N.
}

2 A module M1 has a dependency on a module M2 if any module unit of M1 contains a module-import-declaration nominating M2. A module shall not have a dependency on itself. [Example:
如果模块M1的任何模块单元包含模块导入声明(module-import-declaration)指定了模块M2,那么模块M1依赖于模块M2。模块不应依赖于自身。[ 例:

module M;
import M; // error: cannot import M in its own unit.

3 A module M1 has an interface dependency on a module M2 if the module interface of M1 contains a module-import-declaration nominating M2. A module shall not have a transitive interface dependency on itself. [Example:
如果M1的模块接口包含模块导入声明指定M2,那么模块M1对模块M2具有接口依赖性(interface dependency)。模块不应传递接口依赖于自身。[ 例:

// Interface unit of M1
export module M1;
import M2;
export struct A { };

// Interface unit of M2
export module M2;
import M3;

// Interface unit of M3
export module M3;
import M1; // error: cyclic interface dependency M3 -> M1 -> M2 -> M3

10.7.3 Module exportation 模块导出

1 An exported module-import-declaration nominating a module M’ in the purview of a module M makes all exported names of M’ visible to any translation unit importing M. [ Note: A module interface unit (for a module M) containing a non-exported module-import-declaration does not make the imported names transitively visible to translation units importing the module M. — end note ]
在模块M的范围内一个指定模块M'的导出的模块导入声明(exported module-import-declaration)使所有M'导出的名称对任意导入M的编译单元可见。[ 注:一个模块接口单元(模块M的)包含一个非导出的模块导入声明(non-exported module-import-declaration)不会使导入的名称对导入了模块M的编译单元可见。]

10.7.4 Proclaimed ownership declaration

1 A proclaimed-ownership-declaration asserts that the entities introduced by the declaration are exported by the nominated module. It shall not be a defining declaration.
一个proclaimed-ownership-declaration断言了由指定模块导出的声明引入的实体。它并不是一个声明的定义。

2 The program is ill-formed, no diagnostic required, if the owning module in the proclaimed-ownership-declaration does not export the entities introduced by the declaration.
若proclaimed-ownership-declaration中的模块不导出声明中引入的实体,则程序不合法但不要求诊断(ill-formed, no diagnostic required)。

17 Templates

17.6 Name resolution

17.6.4 Dependent name resolution

This example is currently ill-formed by the current specification. It is an open question as to how often the scenario occurs in practice, and whether to make the example well-formed or whether additional syntax will be introduced that does not involve modifying the header.
按照当前的规范,这个示例目前不合法(ill-formed)。这是一个开放的问题,即场景在实践中发生的频率如何,以及是否要使示例合法(well-formed),或者是否会引入不涉及修改头文件的额外语法。

17.6.4.1 Point of instantiation

The instantiation context of an expression that depends on template arguments is the context of a lookup at the point of instantiation of the enclosing template.
依赖于模板参数的表达式实例化上下文是外围模板实例化位置的查找上下文。

17.7 Template instantiation and specialization

7 If the template argument list of the specialization of an exported template involves a nonexported entity, then the resulting specialization has module linkage and is owned by the module that contains the point of instantiation.
如果导出模板的特化模板参数列表涉及到一个非导出实体,则特化的结果具有模块链接,并且由包含实例化点的模块所拥有。

8 If all entities involved in the template-argument list of the specialization of an exported template are exported, then the resulting specialization has external linkage and is owned by the owning module of the template.
如果一个导出模板的特化模板参数列表中涉及到的所有实体都是导出的,则特化结果具有外部链接,并且由模板所属的模块所拥有。