0

可能的重复:
单个语句中的多个增量运算符
未定义的行为和序列点

有人可以向我解释为什么这行代码会产生这样的输出吗?代码(在将 i&j 都初始化为零之后):

cout<<i++<<','<<++j<<','<<--i<<','<<j--<<'\n';

输出:

-1,0,0,0;

我知道 i++ 意味着先评估然后增加 1,而 ++i 意味着增加 1 然后评估。但不确定顺序 cout 语句中的多重评估是什么行为。

谢谢!

4

2 回答 2

6

该代码的行为未定义。允许实现在它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)fi--

  • i--
  • i++
  • 序列点
  • 称呼g
  • 序列点
  • 称呼f

由于没有分隔i--和的序列点i++,因此会导致未定义的行为。

另一方面,f(g(i+=h()), i++)可以说,在序列点形式主义下只是未指定。我认为它在 C++1x 的关系公式中恢复为未定义。

于 2011-08-29T16:23:03.110 回答
2

C/C++ 中函数的参数求值顺序是Unspecified
传递参数的顺序在<<这里是未指定的,因此是结果。

于 2011-08-29T16:25:50.893 回答