来自 Prasoon's answer关于“未定义的行为和序列点”的问题,我不明白以下是什么意思
.. the prior value shall be accessed only to determine the value to be stored.
作为示例,以下引用在 C++ 中具有未定义的行为:
a[i] = i++;
int x = i + i++;
尽管那里给出了解释,但我不理解这部分(我认为我正确理解了答案的其余部分)。
我不明白上面的代码示例有什么问题。我认为这些编译器具有明确定义的步骤,如下所示。
a[i] = i++;
a[i] = i;
i = i + 1;
int x = i + i++ ;
x = i + i;
i = i + 1;
我错过了什么? “仅应访问先前值以确定要存储的值”是什么意思?
最佳答案
另见 this question和 my answer to it .我不会投票将其作为重复项关闭,因为您询问的是 C++ 而不是 C,但我相信这两种语言的问题是相同的。
the prior value shall be accessed only to determine the value to be stored.
这看起来确实是一个奇怪的要求;为什么标准要关心为什么访问一个值?当您意识到如果读取先前的值以确定要存储在同一对象中的值时,这就隐含地对两个操作强加了一个顺序,因此读取必须发生在写入之前,这是有道理的。由于该顺序,对同一对象的两次访问(一次读取和一次写入)是安全的。编译器无法以导致代码相互干扰的方式重新排列(优化)代码。
另一方面,在像这样的表达式中
a[i] = i++
对 i
有三种访问方式:左侧读取以确定要修改 a
的哪个元素,右侧读取到确定要增加的值,以及将增加的值存储回 i
的写入。 RHS 上的读写是可以的(i++
本身是安全的),但是 LHS 上的读取和 RHS 上的写入之间没有定义的顺序。因此,编译器可以自由地以改变这些读写操作之间关系的方式重新排列代码,并且标准比喻地举手并留下未定义的行为,对可能的后果只字不提。
C11 和 C++11 都更改了这方面的措辞,明确了一些排序要求。 “先验值”的措辞不再存在。引用 C++11 标准草案 1.9p15:
Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced. [...] The value computations of the operands of an operator are sequenced before the value computation of the result of the operator. If a side effect on a scalar object is unsequenced relative to either anotherside effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined.
关于c++ - 'prior value shall be accessed only to determine the value to be stored' 是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9553393/