前提
按照一个定义规则,如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
};
如果我尝试定义b
或foo()
,但是我限于整个程序中的一个定义,我认为这是由于3.2.4中的说明所致:
每个程序应完全包含一个无用的非内部函数或变量的定义 在该计划中;无需诊断。
因此,以下程序形成不佳:
//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:
可以有一个以上的类型定义(第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标准中获取,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
};
请不要说上述代码的评论不是我的,而是直接从标准中复制。
[basic.def.odr]/1:
不包含任何变量,功能,类型,枚举类型或模板的一个定义以上的定义。
变量由[basic]/6:
定义a 变量是由非静态数据成员以外的参考或对象的参考声明引入的。
因此,由于非静态数据成员不是变量,函数,类,枚举或模板,因此,一个定义规则根本不适用于非静态数据成员。
您在第一个程序中没有a
的多个定义。您有a
的多个声明。巨大的差异。
如果您没有多次声明,则include
无法使用,因为预处理器只是在每次使用中使用的信息。