可能的重复:
单个语句中的多个增量运算符
未定义的行为和序列点
有人可以向我解释为什么这行代码会产生这样的输出吗?代码(在将 i&j 都初始化为零之后):
cout<<i++<<','<<++j<<','<<--i<<','<<j--<<'\n';
输出:
-1,0,0,0;
我知道 i++ 意味着先评估然后增加 1,而 ++i 意味着增加 1 然后评估。但不确定顺序 cout 语句中的多重评估是什么行为。
谢谢!
可能的重复:
单个语句中的多个增量运算符
未定义的行为和序列点
有人可以向我解释为什么这行代码会产生这样的输出吗?代码(在将 i&j 都初始化为零之后):
cout<<i++<<','<<++j<<','<<--i<<','<<j--<<'\n';
输出:
-1,0,0,0;
我知道 i++ 意味着先评估然后增加 1,而 ++i 意味着增加 1 然后评估。但不确定顺序 cout 语句中的多重评估是什么行为。
谢谢!
该代码的行为未定义。允许实现在它i++
之前--i
或之后进行评估,或者错开评估,以使最终结果似乎根本没有意义。
当面对诸如
if( k != 0 ) {
cout << i++ << --i;
}
foofum(k);
推理因为then 分支中的代码是未定义的行为,那么我们可以得出结论k
始终为零,并将整个事情简化为
foofum(0);
(这将通过以下事实得到正式证明:未排序更新的“未定义”行为i
可能恰好是分配 0k
并跳转到右大括号。未定义确实意味着任何事情都可能发生)。
只是不要写那样的代码。
编辑:在一个现已删除的答案中建议该语句的效果只是未指定,因为重载<<
的 's 是函数调用而不是本机运算符。然而,就我们目前的目的而言,这只是使该陈述等同于
f(g(i++), i--);
(这里f
代表一个参数,但和ostream::operator<<()
的评估顺序规则是相同的)。编译器可以决定以何种顺序评估. 如果它恰好首先评估,则评估顺序变为:AAA.f(BBB)
f(AAA,BBB)
f
i--
i--
i++
g
f
由于没有分隔i--
和的序列点i++
,因此会导致未定义的行为。
另一方面,f(g(i+=h()), i++)
可以说,在序列点形式主义下只是未指定。我认为它在 C++1x 的关系公式中恢复为未定义。
C/C++ 中函数的参数求值顺序是Unspecified。
传递参数的顺序在<<
这里是未指定的,因此是结果。