繁体   English   中英

如果我不使用odr,可以在翻译单元中对它进行多个定义吗?

[英]If I don't odr-use a variable, can I have multiple definitions of it across translation units?

该标准似乎暗示着,如果不使用变量,则对变量的定义数量没有限制(第3.2 / 3节):

每个程序应准确地包含该程序中使用的每个非内联函数或变量的一个定义; 无需诊断。

它确实说不能在翻译单元(第3.2 / 1节)中多次定义任何变量:

任何变量,函数,类类型,枚举类型或模板的翻译单元均不得包含一个以上的定义。

但是我找不到整个程序中非奇数变量的限制。 那么为什么我不能编译如下内容:

// other.cpp
int x;

// main.cpp
int x;
int main() {}

使用g ++ 4.6.3编译和链接这些文件,对于multiple definition of 'x'出现链接器错误。 老实说,我期望如此,但是由于x并未在任何地方使用(据我所知),所以我看不到标准如何限制了这一点。 还是不确定的行为?

您的程序违反了链接规则。 C ++ 11§3.5[basic.link] / 9指出:

相同且在不同作用域中声明的两个名称应表示相同的变量,函数,类型,枚举器,模板或名称空间

  • 两个名称都具有外部链接,或者两个名称都具有内部链接,并且在同一翻译单元中声明;

  • 这两个名称都引用相同名称空间的成员,或者引用同一类的成员,而不是通过继承。

  • 当两个名称都表示函数时,这些函数的参数类型列表相同;

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

(我引用了完整的段落,以供参考。后两个项目符号在这里不适用。)

在您的程序中,有两个名称x ,它们是相同的。 它们在不同的范围内声明(在这种情况下,它们在不同的翻译单元中声明)。 这两个名称都具有外部链接,并且两个名称都引用相同名称空间(全局名称空间)的成员。

这两个名称并不表示相同的变量。 声明int x; 定义一个变量。 因为程序中有两个这样的定义,所以程序中有两个变量。 一个翻译单位中的名称“ x”表示这些变量之一; 另一个翻译单元中的名称“ x”表示另一个。 因此,该程序格式不正确。

您认为这方面的标准是错误的。 我觉得这种情况落在3.2p1(每个翻译单元最多一个定义,如您所问的问题)和3.2p6(描述类,枚举,内联函数和各种模板如何在整个视图中具有重复定义)之间的空白中翻译单位)。

为了进行比较,在C中,6.9p5要求(我强调):

外部定义是外部声明,它也是函数(内联定义除外)或对象的定义。 如果在表达式中使用了用外部链接声明的标识符(不是作为sizeof_Alignof运算符的操作数的一部分,其结果是一个整数常量),则在整个程序中的某个位置应有一个标识符的外部定义; 否则,不得超过一个

如果standard没有说明未使用变量的定义,那么您不能暗示可能有多个:

当本国际标准省略对行为的任何明确定义的描述时,也可能会出现未定义的行为。

因此它可能会编译并很好地运行,或者可能在翻译过程中由于错误消息而停止,或者可能导致运行时崩溃等。

编辑:请参阅James McNellis回答的标准确实有关于它的规则。

编译没有错误,错误在于它的链接。 默认情况下,全局变量或函数对其他文件是公共的(具有extern存储),因此,当链接器想要链接您的代码时,它会看到x两个定义,并且无法选择其中之一,因此,如果不使用在other.cppmain.cpp x取反, other.cpp使它们other.cpp静态(这意味着仅对包含它的文件可见)

// other.cpp
static int x;

// main.cpp
static int x;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM