非静态数据成员和一个定义规则



前提

按照一个定义规则,如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 
};

如果我尝试定义bfoo(),但是我限于整个程序中的一个定义,我认为这是由于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无法使用,因为预处理器只是在每次使用中使用的信息。

相关内容

  • 没有找到相关文章

最新更新