如果我不使用变量,我可以在翻译单元中有多个定义吗?
标准似乎暗示如果变量不是odr-used(§3.2/3),则对变量的定义数量没有限制:
The standard seems to imply that there is no restriction on the number of definitions of a variable if it is not odr-used (§3.2/3):
每个程序都应包含该程序中 odr 使用的每个非内联函数或变量的准确定义;无需诊断.
Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program; no diagnostic required.
它确实说任何变量都不能在翻译单元中多次定义(第 3.2/1 节):
It does say that any variable can't be defined multiple times within a translation unit (§3.2/1):
任何翻译单元不得包含任何变量、函数、类类型、枚举类型或模板的多个定义.
No translation unit shall contain more than one definition of any variable, function, class type, enumeration type, or template.
但我在整个程序中找不到对非 ODR 使用的变量的限制.那么为什么我不能编译如下内容:
But I can't find a restriction for non-odr-used variables across the entire program. So why can't I compile something like the following:
// other.cpp
int x;
// main.cpp
int x;
int main() {}
使用 g++ 4.6.3 编译和链接这些文件时,我收到 multiple definition of 'x'
的链接器错误.老实说,我期待这一点,但由于 x
在任何地方都没有使用过(据我所知),我看不出标准是如何限制这一点的.还是未定义的行为?
Compiling and linking these files with g++ 4.6.3, I get a linker error for multiple definition of 'x'
. To be honest, I expect this, but since x
is not odr-used anywhere (as far as I can tell), I can't see how the standard restricts this. Or is it undefined behaviour?
推荐答案
你的程序违反了链接规则.C++11 §3.5[basic.link]/9 状态:
Your program violates the linkage rules. C++11 §3.5[basic.link]/9 states:
两个名称相同且在不同范围内声明的应表示相同变量、函数、类型、枚举器、模板或命名空间如果
Two names that are the same and that are declared in different scopes shall denote the same variable, function, type, enumerator, template or namespace if
两个名字都有外部链接,否则两个名字都有内部链接并且在同一个翻译单元中声明;和
both names have external linkage or else both names have internal linkage and are declared in the same translation unit; and
这两个名字都指同一个命名空间的成员或同一个类的成员,而不是继承;和
both names refer to members of the same namespace or to members, not by inheritance, of the same class; and
当两个名称都表示函数时,函数的参数类型列表是相同的;和
when both names denote functions, the parameter-type-lists of the functions are identical; and
当两个名称都表示函数模板时,签名相同.
when both names denote function templates, the signatures are the same.
(我引用了完整的段落,以供参考.后两个项目符号在这里不适用.)
(I've cited the complete paragraph, for reference. The second two bullets do not apply here.)
在你的程序中,有两个名字x
,是一样的.它们在不同的作用域中声明(在这种情况下,它们在不同的翻译单元中声明).两个名称都有外部链接,并且两个名称都引用同一个命名空间(全局命名空间)的成员.
In your program, there are two names x
, which are the same. They are declared in different scopes (in this case, they are declared in different translation units). Both names have external linkage and both names refer to members of the same namespace (the global namespace).
这两个名称不表示同一个变量.int x;
声明定义了一个变量.因为程序中有两个这样的定义,所以程序中有两个变量.一个翻译单元中的名称x"表示这些变量之一;另一个翻译单元中的名称x"表示另一个.因此,该程序是非良构的.
These two names do not denote the same variable. The declaration int x;
defines a variable. Because there are two such definitions in the program, there are two variables in the program. The name "x" in one translation unit denotes one of these variables; the name "x" in the other translation unit denotes the other. Therefore, the program is ill-formed.
相关文章