由于 header 中的匿名命名空间导致 ODR 违规
ODR violation due to anonymous namespace in header
通过阅读标准,我无法确定以下代码是否违反了 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();
// ...
}
据推测,get_v()
在每个翻译单元中引用了不同的变量,因此违反了 ODR
。
这个答案:Inline functions and external linkage 说 inline relaxes ODR
所以我不确定为什么这仍然是一个错误?
有人可以 link 告诉我在标准中指定的地方是否违反了 ODR
吗?
一个inline
函数允许有多个定义(C++17 [basic.def.odr]/6)。这就是 inline
函数可用于防止 ODR 违规的意义。但是inline
函数的多个定义必须相互一致。具体来说,[basic.def.odr]/6.2 说:
in each definition of D
, corresponding names, looked up according to 6.4, shall refer to an entity defined within the definition of D
, or shall refer to the same entity [...] [some exceptions]
get_v
的多个定义引用了变量v
,但是v
没有在get_v
中定义。因此,要求get_v
的每个定义都引用同一个变量v
。事实并非如此,因为每个翻译单元都有不同的 v
。因此,违反了 ODR。
通过阅读标准,我无法确定以下代码是否违反了 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();
// ...
}
据推测,get_v()
在每个翻译单元中引用了不同的变量,因此违反了 ODR
。
这个答案:Inline functions and external linkage 说 inline relaxes ODR
所以我不确定为什么这仍然是一个错误?
有人可以 link 告诉我在标准中指定的地方是否违反了 ODR
吗?
一个inline
函数允许有多个定义(C++17 [basic.def.odr]/6)。这就是 inline
函数可用于防止 ODR 违规的意义。但是inline
函数的多个定义必须相互一致。具体来说,[basic.def.odr]/6.2 说:
in each definition of
D
, corresponding names, looked up according to 6.4, shall refer to an entity defined within the definition ofD
, or shall refer to the same entity [...] [some exceptions]
get_v
的多个定义引用了变量v
,但是v
没有在get_v
中定义。因此,要求get_v
的每个定义都引用同一个变量v
。事实并非如此,因为每个翻译单元都有不同的 v
。因此,违反了 ODR。