非静态数据成员和一个定义规则
non-static data members and one definition rule
前提
根据一个定义规则,如C++14 Standard所述,我可以在每个翻译单元中定义相同的class只要我遵守 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
};
如果我尝试定义 b
或 foo()
,但是,我在整个程序中仅限于一个定义,我认为这是由于 3.2.4 中的声明:
Every program shall contain exactly one definition of every non-inline function or variable that is odr-used
in that program; no diagnostic required.
因此,以下程序格式错误:
//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;
如果我尝试在两个源文件中定义 foo()
,结果相同。
但是,我可以有多个 boo()
定义(每个翻译单元一个),因为 3.2.4 不禁止,实际上 3.2.6 明确允许:
There can be more than one definition of a class type (Clause 9), enumeration type (7.2), inline function with
external linkage (7.1.2), class template (Clause 14), non-static function template (14.5.6), static data member
of a class template (14.5.1.3), member function of a class template (14.5.1.1), or template specialization for
which some template parameters are not specified (14.7, 14.5.5) in a program provided that each definition
appears in a different translation unit.
为了公平起见,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
};
请注意,上面代码的注释不是我的,而是直接从标准中复制的。
您在第一个程序中没有 a
的多个 定义 。您有 a
的多个 声明 。差别很大。
如果您不能有多个声明,那么 include
将无法工作,因为预处理器只是在它使用的每个翻译中复制该信息。
[basic.def.odr]/1:
No translation unit shall contain more than one definition of any variable, function, class type, enumeration type, or template.
变量定义为[basic]/6:
A variable is introduced by the declaration of a reference other than a non-static data member or of an object.
因此,由于非静态数据成员不是变量、函数、class、枚举或模板,所以单一定义规则根本不适用于非静态数据成员。
前提
根据一个定义规则,如C++14 Standard所述,我可以在每个翻译单元中定义相同的class只要我遵守 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
};
如果我尝试定义 b
或 foo()
,但是,我在整个程序中仅限于一个定义,我认为这是由于 3.2.4 中的声明:
Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program; no diagnostic required.
因此,以下程序格式错误:
//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;
如果我尝试在两个源文件中定义 foo()
,结果相同。
但是,我可以有多个 boo()
定义(每个翻译单元一个),因为 3.2.4 不禁止,实际上 3.2.6 明确允许:
There can be more than one definition of a class type (Clause 9), enumeration type (7.2), inline function with external linkage (7.1.2), class template (Clause 14), non-static function template (14.5.6), static data member of a class template (14.5.1.3), member function of a class template (14.5.1.1), or template specialization for which some template parameters are not specified (14.7, 14.5.5) in a program provided that each definition appears in a different translation unit.
为了公平起见,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
};
请注意,上面代码的注释不是我的,而是直接从标准中复制的。
您在第一个程序中没有 a
的多个 定义 。您有 a
的多个 声明 。差别很大。
如果您不能有多个声明,那么 include
将无法工作,因为预处理器只是在它使用的每个翻译中复制该信息。
[basic.def.odr]/1:
No translation unit shall contain more than one definition of any variable, function, class type, enumeration type, or template.
变量定义为[basic]/6:
A variable is introduced by the declaration of a reference other than a non-static data member or of an object.
因此,由于非静态数据成员不是变量、函数、class、枚举或模板,所以单一定义规则根本不适用于非静态数据成员。