Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
353 views
in Technique[技术] by (71.8m points)

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

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):

Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program; no diagnostic required.

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.

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() {}

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.)

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).

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...