简体   繁体   English

如何在标头中使用未命名的命名空间会导致ODR违规?

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

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). " 在Google C ++样式指南中, 命名空间部分指出“ 在头文件中使用未命名的命名空间很容易导致违反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. 我理解为什么不在实现文件中使用未命名的命名空间可能会导致ODR违规,但不能在标头中使用它们。 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. 在这种情况下,每个翻译单元具有单独的pi实例,因此两个twoPiRpi绑定到每个翻译单元中的不同实体。 (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. 当然,即使没有匿名命名空间,这也是未定义的行为(因为const默认意味着内部链接),但基本原则成立。 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. 在未命名的命名空间(或标头中定义的任何const对象)中的任何内容的标头中的任何使用都可能导致未定义的行为。 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. 它是否是一个真正的问题取决于,但肯定涉及上述pi的地址的任何事情都会引起问题。 (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.) (我在这里说“真的”,因为很多情况下地址或引用都是正式使用的,但实际上,内联扩展会导致实际使用的值。当然,令牌3.141593.14159而不管它出现的地方。)

In test.h 在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. 在任何源文件中包含该头文件都会导致ODR违规,因为x被定义了两次。 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. 换句话说:每个TU最多只有一个未命名的命名空间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 关于ODR违规和模板变量 - About ODR-violations and template variables 是否需要一个实现来诊断同一 TU 内同一显式专业化的重复定义的 ODR 违规? - Is an implementation required to diagnose ODR-violations of duplicated definitions of the same explicit specialization within the same TU? 在内联函数的定义中使用 constexpr 变量时可能的 ODR 违规(在 C++14 中) - Possible ODR-violations when using a constexpr variable in the definition of an inline function (in C++14) 在这种情况下如何防止 ODR 违规? - How to prevent ODR violations in this case? 标头中的“const”和“constexpr”变量是否应为“内联”以防止违反 ODR? - Should `const` and `constexpr` variables in headers be `inline` to prevent ODR violations? Boost.Exception符号出现在“ nm”输出中是什么意思? 它们会导致违反ODR吗? - What does it mean when Boost.Exception symbols show up in 'nm' output? Will they cause ODR violations? 我应该在实现文件中使用未命名的命名空间吗? - Should I use unnamed namespaces in implementation files? 使用未命名的命名空间会减少链接时间吗? - Does use of unnamed namespaces reduce link time? 标头和ODR中的类定义? - Class definitions in headers and ODR? 我可以在函数内部使用未命名的命名空间代替静态变量吗? - Can I use unnamed namespaces instead of static variables inside functions?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM