Geo*_*y91 5 c++ scope class one-definition-rule linkage
前提
按照一个定义规则,如C++14标准所述,只要我遵循3.2.6中的规则,我就可以在每个翻译单元中定义相同的类。这意味着允许以下程序合法:
//a_1.cpp
class A { //definition of A
int a; //definition of A::a
static int b; //declaration of A::b
int foo(); //declaration of A::foo();
int boo(){ return 42; }; //definition of A::boo() implicity inlined
};
//a_2.cpp
class A { //definition of A
int a; //definition of A::a
static int b; //declaration of A::b
int foo(); //declaration of A::foo();
int boo(){ return 42; }; //definition of A::boo() implicity inlined
};
Run Code Online (Sandbox Code Playgroud)
但是,如果我尝试定义bor foo(),则仅限于整个程序中的单个定义,我认为这是由于 3.2.4 中的语句:
每个程序都应包含该程序中 odr 使用的每个非内联函数或变量的一个定义;无需诊断。
因此,以下程序格式错误:
//a_1.cpp
class A { //definition of A
int a; //definition of A::a
static int b; //declaration of A::b
int foo(); //declaration of A::foo();
int boo(){ return 42; }; //definition of A::boo() implicity inlined
};
int A::b;
//a_2.cpp
class A { //definition of A
int a; //definition of A::a
static int b; //declaration of A::b
int foo(); //declaration of A::foo();
int boo(){ return 42; }; //definition of A::boo() implicitly inlined
};
int A::b;
Run Code Online (Sandbox Code Playgroud)
如果我试图foo()在两个源文件中定义,也是如此。
但是,我可以有多个定义boo()(每个翻译单元一个),因为 3.2.4 不禁止这样做,实际上 3.2.6 明确允许:
类类型(第 9 条)、枚举类型(7.2)、具有外部链接的内联函数(7.1.2)、类模板(第 14 条)、非静态函数模板(14.5.6)可以有多个定义、类模板的静态数据成员 (14.5.1.3)、类模板的成员函数 (14.5.1.1) 或在程序中未指定某些模板参数的模板特化 (14.7, 14.5.5),前提是每个定义出现在不同的翻译单元中。
公平地说,3.2.6 限定了上面的语句,添加了一些要求,其中实体(在我们的例子中boo())必须在每个翻译单元中用相同的标记序列定义。
题
非静态数据成员a呢?的多个定义a显然是允许的(否则我问题顶部的程序将无法编译),但这似乎被 3.2.4 禁止,并且不被 3.2.6 宽恕。这只是标准中没有严格规定的细节还是我遗漏了什么?
编辑
对于那些向我指出a未定义而只是声明的人,请考虑这个直接取自C++14 Standard 3.2.2 的示例:
struct X { // defines X
int x; // defines non-static data member x
static int y; // declares static data member y
X(): x(0) { } // defines a constructor of X
};
Run Code Online (Sandbox Code Playgroud)
请注意,上面代码的注释不是我的,而是直接从标准中复制的。
[basic.def.odr]/1:
任何翻译单元不得包含任何变量、函数、类类型、枚举类型或模板的多个定义。
变量由[basic]/6定义:
变量是通过声明非静态数据成员或对象的引用来引入的。
因此,由于非静态数据成员不是变量、函数、类、枚举或模板,因此单一定义规则根本不适用于非静态数据成员。