在C和C++语言中,arr[i] = i++;
语句会导致未定义的行为。为什么i = i + 1;
语句不会导致未定义的行为?
在C和C++语言中,arr[i] = i++;
语句会导致未定义的行为。为什么i = i + 1;
语句不会导致未定义的行为?
C ++ 17
开始,行为已更改。请参见此 Barry的答案以了解更多信息。
对于该语句
arr[i] = i++;
i
的值在RHS(右操作数)和LHS(左操作数)中都被使用,在其中一种情况下,该值正在被修改(作为post ++
的副作用),而在这两个操作之间没有序列点来确定应考虑哪个i
的值。您还可以查看this canonical answer以了解更多信息。i = i + 1
,i
的值仅在RHS中使用,计算结果存储在LHS中,换句话说,没有歧义。我们可以将相同的语句写成i ++
,其中
i
的值1
i
中i=++i;
合法化。 - 6502i = i + 1
不等同于 i++
,它的效果等同于 ++i
。通过比较 j = i = i+1
和 j = ++i
以及 j = i++
的影响来理解区别(应记住赋值运算符从右至左结合,因此 j = i = i+1
等同于 j = (i = i+1)
)。 - Peteri=i+1
和i++
是等价的,但它们并不等价。这种建议对回答问题是不必要的,也会产生误导。 - Peterarr [i] = i ++
不会引发未定义的行为。 这是由于[expr.ass]中以下更改造成的:i ++
,然后执行arr [i]
,然后执行分配。现在明确定义的顺序是:auto src = i++;
auto& dst = arr[i];
dst = src;
arr[i] = i++
怎么会是双重存储呢? - Daniel Harr[i] = i++;
这意味着:
但是对于右侧表达式的计算顺序和下标操作符的计算顺序存在歧义,编译器可以将其视为:
auto & val{arr[i]};
i++;
auto const rval{i};
val = rval;
i++;
auto & val{arr[i]};
auto const rval{i};
val = rval;
或者(与上面相同的结果)
i++;
auto const rval{i};
auto & val{arr[i]};
val = rval;
i = i + 1;
没有任何歧义,右手表达式在赋值之前被求值:
auto const rval{i + 1};
auto & val{i};
val = rval;
或(与上述结果相同)
auto & val{i};
auto const rval{i + 1};
val = rval;
undefined();
。 - Deduplicator