c ++ 11多个定义没有使用odr?

时间:2013-08-31 11:15:23

标签: c++ gcc c++11

考虑以下C ++ 11程序:

翻译单位#1:

int x = 3;

int main() {}

翻译单元#2:

int x = 4;

这个节目是不是形成了?为什么/为什么不呢?

gcc抱怨说:

error: multiple definition of `x'

我能看到的唯一相关规则是3.2.4:

  

每个程序应该只包含该程序中使用的每个非内联函数或变量的一个定义

x在程序中没有使用。 (或者是吗?)

这是一个gcc bug吗?或者我错过了标准中的某些内容?

2 个答案:

答案 0 :(得分:2)

这不是gcc错误,而是标准行为。

实际上,int x;定义了一个符号,如果定义了两次或更多,则会导致链接器错误。

C++ standard 3.5(9)

  

两个相同的名称(第3条)并且在不同的范围内声明,如果

,则表示相同的变量,函数,类型,枚举器,模板或名称空间。

- 两个名称都有外部链接,否则两个名称都有内部链接,并在同一个翻译单元中声明;和

- 两个名称引用同一名称空间的成员或同一类的成员,而不是继承。和

- 当两个名称都表示函数时,函数的参数类型列表(8.3.5)是相同的;和

- 当两个名称都表示功能模板时,签名(14.5.6.1)是相同的。

答案 1 :(得分:1)

我知道您正在根据标准寻找解释,但在这种情况下,我认为没有必要。

全局变量和函数声明,除非声明为static,否则具有外部链接。

具有初始化的声明计为定义。您在两个地方声明了相同的变量x,并使用2个不同的值初始化它。 (事实上​​,它甚至可能是相同的值。)

意思是,您有两个相同变量的定义。这是肯定的。

意思是,您的上述示例违反了ODR。

我记得即使是在C的史前时期也是如此。

在C ++中,我们可以将所有全局定义放在static内,而不是使用anonymous namespace,效果是相同的。