【问题标题】:ODR violation due to anonymous namespace in header由于标头中的匿名命名空间导致 ODR 违规
【发布时间】:2020-04-09 01:52:28
【问题描述】:

通过阅读标准,我无法确定以下代码是否违反 ODR:

// a.h
#ifndef A_HEADER_FILE
#define A_HEADER_FILE

namespace {
int v;
}

inline int get_v() { return v; }

#endif // A_HEADER_FILE

// a.cpp
#include "a.h"

void f() {
  int i = get_v();
  // ...
}

// b.cpp
#include "a.h"

void g() {
  int i = get_v();
  // ...
}

(来源:https://wiki.sei.cmu.edu/confluence/display/cplusplus/DCL59-CPP.+Do+not+define+an+unnamed+namespace+in+a+header+file

据推测,get_v() 在每个翻译单元中引用了不同的变量,因此它违反了ODR

这个答案:Inline functions and external linkage 说内联放松了ODR 所以我不知道为什么这仍然是一个错误?

如果这是 ODR 违规,有人可以将我链接到标准中指定的位置吗?

【问题讨论】:

    标签: c++ language-lawyer linkage one-definition-rule inline-functions


    【解决方案1】:

    inline 函数允许有多个定义 (C++17 [basic.def.odr]/6)。这就是 inline 函数可用于防止 ODR 违规的意义。但是inline函数的多个定义必须相互一致。具体来说,[basic.def.odr]/6.2 说:

    D 的每个定义中,根据6.4 查找的相应名称应指在D 定义中定义的实体,或应指同一实体[...] [某些例外]

    get_v 的多个定义引用了变量v,但v 没有在get_v 中定义。因此,要求get_v 的每个定义都引用同一个变量v。情况并非如此,因为每个翻译单元都有不同的v。因此,违反了 ODR。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-01
      • 2010-09-26
      • 2011-11-29
      • 2011-05-10
      • 1970-01-01
      • 2016-09-13
      • 2016-11-01
      相关资源
      最近更新 更多