在我阅读的过程中出现了这个问题(答案) 那么为什么i = ++ i + 1在C++ 11中定义明确?
我认为,微妙的解释是(1)表达式++i返回一个左值但是+将prvalues作为操作数,因此必须执行从左值到右值的转换; 这涉及获得该左值的当前值(而不是旧值的一个以上i),因此必须在增量的副作用(即更新)之后进行排序i(2)赋值的LHS也是左值,所以它的价值评估不涉及取得当前价值i; 虽然这个值计算在RHS的值计算中是不可测的,但这没有问题.(3)赋值本身的值计算涉及更新i(再次),但是在其RHS的值计算之后排序,因此在变换之后更新到i; 没问题.
很好,所以那里没有UB.现在我的问题是如果将分配运算符更改=为+=(或类似的运算符).
表达式的评估是否会
i += ++i + 1导致未定义的行为?
在我看来,标准似乎在这里自相矛盾.由于LHS +=仍然是左值(并且其RHS仍然是prvalue),所以与上述相同的推理适用于(1)和(2); 在操作数的评估中没有未定义的行为+=.至于(3),复合赋值的运算+=(更确切地说是该运算的副作用;它的值计算,如果需要,在任何情况下在其副作用之后排序)现在必须同时获取当前值i,然后(显然在它之后排序,即使标准没有明确说明,或者对这些运算符的评估总是会调用未定义的行为)添加RHS并将结果存回i.如果它们的副作用没有排序,这两个操作都会给出未定义的行为++,但正如上面所论述的那样(在给出运算符的RHS ++的值计算之前对其进行排序的副作用,该计算值在计算之前排序.该复合转让的操作),情况并非如此.++=
但另一方面,标准也表示E += F相当于E = E + F,除了(左值)E仅被评估一次.现在在我们的例子中,作为左值的i(E …
有人可以解释一下是否i = x[i]++;会导致未定义的行为吗?
注意:x[i]和i并不都是易失性的且不x[i]重叠i。
有 C11,6.5 表达式,2(添加强调):
\n\n\n如果标量对象上的副作用相对于同一标量对象的不同副作用或使用同一标量对象的值的值计算而言是无序的,则该行为是未定义的。如果表达式的子表达式有多个允许的\n排序,并且在任何排序中出现这种未排序的副作用,则行为是未定义的。84)
\n
我认为:
\n是否有“多重允许的订购”?
\n总体而言:如何i = x[i]++;解释序列点、副作用和未定义的行为(如果有)?
UPD。结论:会i = x[i]++;导致 2 个副作用:
该标准没有定义副作用发生的顺序。
\n因此,根据 C11,4. 一致性,2:
\n\n\n未定义的行为在本国际标准中另外通过文字 \xe2\x80\x98\xe2\x80\x98undefinedbehavior\xe2\x80\x99\xe2\x80\x99 或通过省略任何明确的行为定义来表示。
\n
实验表明,GCC/LLVM/ICC 有序1-2,而 …