One Definition Rule: Can corresponding entities ha

2019-07-16 10:09发布

I read and reread the relevant clauses about ODR in the C++ standard, but this question still remains open to me. The standard says that the definition of an inline function shall appear in every translation unit in which it is used, and the definitions shall be identical in a sense which is described in almost a page. It says the token sequence must be the same. Does it include the local identifier names?

In other words does the following program violate the ODR? (I tried to test it myself with Visual Studio 2008 and got 0 errors and 0 warnings. But I guess this doesn't prove anything, because I then changed the example to two completely different definitions and still got 0 errors and 0 warnings. In excuse of MSVC it should be noted that no diagnostic is formally required for violations of ODR).

//main.cpp
inline int f(int);
int main(){
   f(3);
}
int f(int x){
   int z = x;
   return z*z;
}

//other.cpp
inline int f(int xx){
   int zz = xx;
   return zz*zz;
}

3条回答
地球回转人心会变
2楼-- · 2019-07-16 10:50

Identifiers are tokens, so by the same sequence of tokens rule, the program violates the ODR.

查看更多
孤傲高冷的网名
3楼-- · 2019-07-16 10:52

Identifier is a kind of token, each identifier is a separate token, so yes, you need to have the same identifier to respect the ODR. It can make a difference in a compiler which detect this (someone ready to build an example for como with exported template? it can detect some violation of the ODR).

Then there is a difference between C and C++ here. C doesn't have the ODR in general and the rules for inline function in C99 (there is no inline functions in C90) are quite different to those of C++. In C99, your code is correct. In fact you can provide completely different definition. A consequence is that in C (but not in C++), if you use the same definition and that definition has a static member, you have in fact as many static variables as TU using the function.

查看更多
唯我独甜
4楼-- · 2019-07-16 10:58

Yes, it violates ODR. It uses different token sequences, I don't know what's so hard to understand here.

Verifying ODR across translation units is hard (impossible) with traditional compilation techniques. The standard says that "No diagnostics required", so you just get undefined behavior.

You may get even more subtle errors when you use e.g. two different classes defined in unrelated translation units but with the same name. If there is a virtual table it may clash without any error messages (it happened to my friend). So always use a anonymous namespaces for local functions and classes.

查看更多
登录 后发表回答