c++ - 在 header 中使用未命名的 namespace 会如何导致 ODR 违规?

标签 c++ one-definition-rule unnamed-namespace

在 Google C++ 风格指南中,Namespaces部分指出“在头文件中使用未命名的命名空间很容易导致违反 C++ 统一定义规则 (ODR)。

我明白为什么在实现文件中使用未命名的命名空间会导致 ODR 违规,但不知道在 header 中使用如何做到这一点。这怎么会导致违规?

最佳答案

原因是如果你真的在匿名中使用任何东西 命名空间,你冒着未定义行为的风险。例如:

namespace {
double const pi = 3.14159;
}

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

内联函数(以及类、模板和 任何其他必须在多重翻译中定义的东西 单位)是 token 必须相同(通常情况下, 除非你打了一些宏),并且所有符号都必须绑定(bind) 同样地。在这种情况下,每个翻译单元都有一个单独的 pi 的实例,所以 twoPiR 中的 pi 绑定(bind)到一个不同的 每个翻译单元中的实体。 (有一些异常(exception), 但它们都涉及整数表达式。)

当然,即使没有匿名命名空间,这也是 这里的未定义行为(因为 const 表示内部链接 默认),但基本原则成立。在标题中的任何使用 未命名命名空间中的任何内容(或定义在 header )很可能会导致未定义的行为。无论 是不是一个真正的问题取决于,但肯定是任何 确实涉及到pi的地址,上面,会导致 问题。 (我这里说“真的”,因为有很多情况 正式使用地址或引用的地方,但在 实际上,内联扩展将导致实际值 正在使用。当然, token 3.141593.14159 不管它出现在哪里。)

关于c++ - 在 header 中使用未命名的 namespace 会如何导致 ODR 违规?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23652156/

相关文章:

C 在不同文件中定义的相同全局变量

c++ - 将 void* 转换为 std::function<void()>

c++ - 为什么不同 TU 中的 `static` 函数不会破坏 ODR?

c++ - C++中具有O(1)搜索时间复杂度的数据结构

c++ - 为什么 one-definition-rule-use (odr-use) 取决于上下文?

c++ - 两个未命名的命名空间,在同一个声明区域中定义

c++ - 非内联命名空间不能作为内联重新打开

c++ - 如何检查鼠标是否在控件上

c++ - 用于 C/C++ 的可移植 zip 库(不是应用程序)