【问题标题】:using constants in header file with ODR compliance在符合 ODR 的头文件中使用常量
【发布时间】:2016-12-14 01:21:53
【问题描述】:

查看another question 我意识到我不能通过头文件使用来自匿名命名空间的对象或函数,因为它会导致类定义或内联函数中的 ODR 冲突。如果是这种情况,那么是否可以在 inline 函数或类中安全地使用命名为 constconstexpr 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++17 中这不再是问题。奇怪的是,类型别名可以解决您的问题:using CONSTANT = std::integral_constant<int, 2>;
  • @Barry 从 M.M 的引用中删除了我收集的 C++17 中的“对象未被使用”?
  • N4606(这是根据 isocpp.org 的最新标准草案)仍然有“对象未使用 odr”
  • @M.M 对不起,我一开始以为会这样……等待巴里的回应
  • @RyanHaining N4606 的日期在该文档之后,并且该文档和 N4606 之间的某些文本有所不同,因此我们需要小心

标签: c++ c++11 one-definition-rule


【解决方案1】:

这段代码没问题。完整的段落(C++14 [basic.def.odr/6.2])是:

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

这种用法确实符合“除了...和...和...”部分中的所有条件:

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

“它不是 odr-used”这一点应该表示“它不是 odr-usedf() 内”——即它没有如果您碰巧在程序中的其他地方odr-use CONSTANT,请打破 f()

【讨论】:

  • 这绝对应该是指“在D的定义中不使用odr”。
猜你喜欢
  • 2016-03-30
  • 2016-04-15
  • 2015-12-25
  • 2014-06-22
  • 2012-08-06
  • 1970-01-01
  • 2014-11-07
  • 1970-01-01
相关资源
最近更新 更多