在符合 ODR 标准的头文件中使用常量

using constants in header file with ODR compliance

本文关键字:文件 常量 ODR 标准      更新时间:2023-10-16

看着另一个问题,我意识到我不能通过头文件使用匿名命名空间中的对象或函数,因为它会导致类定义或内联函数中的 ODR 违规。如果是这种情况,那么是否可以安全地在inline函数或类中使用命名constconstexprstatic对象?例如,如果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])是:

D的每个定义中,根据 3.4 查找的相应名称应指D定义中定义的实体,或应指同一实体,在重载解析和部分模板专用化匹配后,除了名称可以指非易失性 具有内部链接或无链接的 const 对象,如果该对象在D的所有定义中具有相同的文字类型,并且该对象使用常量表达式初始化,并且该对象未被 ODR 使用,并且该对象在D的所有定义中具有相同的值;和

此用法确实符合"除了...和。。。而且...".part:

  • CONSTANT这个名字实际上指的是具有内部链接的非易失性const对象
  • 它在f()的所有定义中具有相同的文字类型。
  • 它使用常量表达式2初始化。
  • 它不是odr 使用的
  • 它在f()的所有定义中具有相同的值。

"它不是odr-used"这一点应该意味着"它不是在f()中使用odr的"——也就是说,如果你碰巧在程序的其他地方使用odr-useCONSTANT,它不会破坏f()