继续"我无法理解DR 712"

时间:2017-03-01 14:36:24

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

这基本上是关于DR 712的my prior question的延续。让我首先解释为什么我坚持要查看可能被认为是旧的东西,如C ++ 11标准,但我的问题在[C ++ 11]中已经很难理解[basic.def.odr]部分了,在我深入研究当前草案中的相同部分之前我想完全涵盖这一部分,在我看来,这个部分更加复杂

Austing Hasting的先前问题的答案很棒,但我仍然有一点在C ++ 11的[basic.def.odr] / 2中不明确。考虑一下这个非常简单的例子:

const int i = 1;
int main()
{
    int j = i;
}

来自C ++ 11 [{1}}中的[basic.def.odr] / 2,i中的不是 odr-used,因为int j = i;是满足出现在常量表达式中的要求的对象,并且左值到右值的转换会立即应用于i。这对我来说没有多大意义,因为i在声明i中被清晰地使用,正如在here显示的略微修改的代码中可以看到的那样,我强迫变量int j = i;不能从编译的代码中优化。

当然,上面的推理肯定有问题,因为我不相信C ++ 11在这么简单的例子中可能是错的。再一次,我现在想念的是什么?

1 个答案:

答案 0 :(得分:9)

我试图翻译我对标准的理解"用过"和"使用的一个定义规则"在这里更直观的东西。使用"以外的条款"和" ODR使用"不属于以下标准定义的术语。

使用ODR的东西基本上意味着"我们需要它来拥有身份"。这通常意味着有人正在引用它或指针。

如果您只需要某些内容的,则不会总是使用ODR。编译时常量的值不需要标识。

在C ++中,身份基本上意味着"它实际上必须在某处存储"。

标准没有说"如果我们需要它来拥有身份而使用ODR,因为那时不同的编译器将有不同的规则来确定他们是否需要身份。例如,如果内联操作并且引用被省略,这是否意味着它不再需要身份?

因此,该标准描述了ODR使用的含义,并将其与所使用的值区分开来。

int j = i;

这不需要i的身份。它只需要它的价值。 const int i = 1;的值不会(在定义的行为下)发生变化。

int const* pj = &i;

需要一个身份。 i的两个不同指针必须就i在标准下的位置达成一致。

void foo( const int& x ) {
  int j = x;
}
foo(i);

这也需要i的身份。我们引用i。尽管我们做的唯一事情就是引用它的价值,但该引用的(简短的,理论上的)存在意味着它具有一种身份。

const int a = 3; const int b = 4;
int i = (a<2)?a:b;

缺陷是,这需要ab具有身份(它们使用ODR),因为?与使用规则的交互。缺陷是说&#34;我们应该解决这个问题&#34;。

Link to DR 712

在该决议之后,该表达式只需要ab的值,而不是他们的身份,因此他们不需要存储。

我们关心某些东西是否存储,因为需要存储的东西必须具有独特的定义点。它们基本上不能完全存在于头文件中。

请注意,对于C ++中的内联变量,我们可能不太关心这一点;在as-if规则下,如果没有人真正关注身份,则可以删除创建的内联存储位置。因为const&可以&#34;意外地&#34;强制身份要求的东西只是有价值的令牌,这是一个很好的放松规则。