boy*_*ycy 6 c++ one-definition-rule unnamed-namespace
在Google C++样式指南中,命名空间部分指出" 在头文件中使用未命名的命名空间很容易导致违反C++ One Definition Rule(ODR). "
我理解为什么不在实现文件中使用未命名的命名空间可能会导致ODR违规,但不能在标头中使用它们.这怎么会导致违规?
原因是,如果您实际使用匿名命名空间中的任何内容,则存在未定义行为的风险.例如:
namespace {
double const pi = 3.14159;
}
inline double twoPiR( double r ) { return 2.0 * pi * r; }
Run Code Online (Sandbox Code Playgroud)
内联函数(以及类和模板以及必须在多个翻译单元中定义的任何其他内容)的规则是令牌必须相同(通常情况下,除非您点击某个宏),并且所有符号必须以相同方式绑定.在这种情况下,每个翻译单元都有一个单独的实例pi
,因此pi
in twoPiR
绑定到每个翻译单元中的不同实体.(有一些例外,但它们都涉及整体表达.)
当然,即使没有匿名命名空间,这也是未定义的行为(因为const
默认情况下意味着内部链接),但基本原则成立.在未命名的命名空间(或标头中定义的任何const对象)中的任何内容的标头中的任何使用都可能导致未定义的行为.它是否是一个真正的问题取决于,但肯定涉及上述地址的任何事情pi
都会引起问题.(我说"真的"在这里,因为有很多情况下地址或引用正式使用,但在实践中,内联扩展将导致实际使用的价值.当然,令牌3.14159
是3.14159
无论它出现.)