在符合 ODR 的头文件中使用常量
using constants in header file with ODR compliance
查看 another question 我意识到我不能通过头文件使用来自匿名名称空间的对象或函数,因为它会导致 class 定义或内联函数中的 ODR 违规。如果是这种情况,那么是否可以在 inline
函数或 classes 中安全地使用命名 const
或 constexpr
static
对象?例如,如果 CONSTANT
在下面的 namespace
内,那将是不安全的,但是可以使用带有静态链接的常量吗?
// some header file to be included by multiple .cpp files
static const/*expr*/ int CONSTANT = 2;
inline int f() {
return CONSTANT;
}
class Cls {
int mem = CONSTANT;
};
这段代码没问题。完整段落 (C++14 [basic.def.odr/6.2]) 是:
in each definition of D
, corresponding names, looked up according to 3.4, shall refer to an entity defined within the definition of D
, or shall refer to the same entity, after overload resolution and after matching of partial template specialization, except that a name can refer to a non-volatile
const object with internal or no linkage if the object has the same literal type in all definitions of D
, and the object is initialized with a constant expression, and the object is not odr-used, and the object has the same value in all definitions of D
; and
这种用法确实符合 "except ... and ... and ..." 部分中的所有条件:
- 名称
CONSTANT
实际上是指具有内部链接的非易失性 const
对象
- 它在
f()
的所有定义中具有相同的文字类型。
- 它是用常量表达式
2
初始化的。
- 它不是 odr-used。
- 它在
f()
的所有定义中具有相同的值。
点 "It is not odr-used" 应该意味着 "It is not odr-used within f()
" —— 即它不会破坏 f()
如果你碰巧 odr-use CONSTANT
在程序的其他地方。
查看 another question 我意识到我不能通过头文件使用来自匿名名称空间的对象或函数,因为它会导致 class 定义或内联函数中的 ODR 违规。如果是这种情况,那么是否可以在 inline
函数或 classes 中安全地使用命名 const
或 constexpr
static
对象?例如,如果 CONSTANT
在下面的 namespace
内,那将是不安全的,但是可以使用带有静态链接的常量吗?
// some header file to be included by multiple .cpp files
static const/*expr*/ int CONSTANT = 2;
inline int f() {
return CONSTANT;
}
class Cls {
int mem = CONSTANT;
};
这段代码没问题。完整段落 (C++14 [basic.def.odr/6.2]) 是:
in each definition of
D
, corresponding names, looked up according to 3.4, shall refer to an entity defined within the definition ofD
, or shall refer to the same entity, after overload resolution and after matching of partial template specialization, except that a name can refer to a non-volatile const object with internal or no linkage if the object has the same literal type in all definitions ofD
, and the object is initialized with a constant expression, and the object is not odr-used, and the object has the same value in all definitions ofD
; and
这种用法确实符合 "except ... and ... and ..." 部分中的所有条件:
- 名称
CONSTANT
实际上是指具有内部链接的非易失性const
对象 - 它在
f()
的所有定义中具有相同的文字类型。 - 它是用常量表达式
2
初始化的。 - 它不是 odr-used。
- 它在
f()
的所有定义中具有相同的值。
点 "It is not odr-used" 应该意味着 "It is not odr-used within f()
" —— 即它不会破坏 f()
如果你碰巧 odr-use CONSTANT
在程序的其他地方。