How would use of unnamed namespaces in headers cause ODR-violations?

*爱你&永不变心* 提交于 2019-12-03 14:22:21

The reason is that if you actually use anything in the anonymous namespace, you risk undefined behavior. For example:

namespace {
double const pi = 3.14159;
}

inline double twoPiR( double r ) { return 2.0 * pi * r; }

The rule for inline functions (and classes, and templates, and anything else which must be defined in multiple translation units) is that the tokens must be identical (normally the case, unless you hit some macro), and that all symbols must bind identically. In this case, each translation unit has a separate instance of pi, so the pi in twoPiR binds to a different entity in each translation unit. (There are a few exceptions, but they all involve integral expressions.)

Of course, even without the anonymous namespace, this would be undefined behavior here (since const means internal linkage by default), but the basic principle holds. Any use in a header of anything in an unnamed namespace (or any const object defined in the header) is likely to cause undefined behavior. Whether it is a real problem or not depends, but certainly anything which really involves the address of pi, above, is going to cause problems. (I say "really" here, because there are many cases where the address or a reference is formally used, but in practice, the inline expansion will result in the value actually being used. And of course, the token 3.14159 is 3.14159 regardless of where it appears.)

Rakib

In test.h

namespace {
  int x;
}

namespace{
  int x;
}

Including that header file in any source file will case ODR violation, since x is defined twice. This occurs because an unnamed namespace is given a unique identifer by the compiler, and all occurrences of an unnamed namespace in a translation unit are given the same identifier. To paraphrase: every TU has at most one unnamed namespace.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!