如何在标头中使用未命名的命名空间会导致ODR违规? [英] How would use of unnamed namespaces in headers cause ODR-violations?

查看:171
本文介绍了如何在标头中使用未命名的命名空间会导致ODR违规?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Google C ++样式指南中,命名空间部分



我理解为什么要使用未命名的命名空间在头文件中容易导致违反C ++ One Definition Rule(ODR)在实施文件中使用未命名的命名空间可能会导致ODR违规,但不会影响标题中的使用方式。

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

 命名空间{
double const pi = 3.14159;
}

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

内联函数(以及类和模板以及
)的规则必须在多个翻译
单位中定义)是令牌必须是相同的(通常情况下,
,除非你敲一些宏),并且所有符号必须同样绑定
。在这种情况下,每个翻译单元都有一个单独的
实例 pi ,因此 pi c $ c> twoPiR 绑定到每个翻译单元中不同的
实体。 (有一些例外,
,但它们都涉及整数表达式。)



当然,即使没有匿名命名空间,这将是
未定义的行为这里(因为 const 表示内部链接通过
默认),但基本原则成立。在未命名的命名空间(或
中定义的任何const对象的头)中
任何东西的头部中的任何使用都可能导致未定义的行为。不管它是
是一个真正的问题或不依赖,但肯定任何
真正涉及 pi 的地址,将导致
的问题。 (我在这里说真的,因为有很多情况
地址或引用正式使用,但在
练习中,内联展开将导致实际上使用
的值当然,令牌 3.14159 3.14159
,不管它出现在哪里。)


In the Google C++ Style Guide, the Namespaces section states that "Use of unnamed namespaces in header files can easily cause violations of the C++ One Definition Rule (ODR)."

I understand why not using unnamed namespaces in an implementation file can cause ODR-violations, but not how use in a header can do so. How can this cause a violation?

解决方案

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

这篇关于如何在标头中使用未命名的命名空间会导致ODR违规?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆