对于一元操作如何导致此输出感到困惑

时间:2011-08-29 16:20:30

标签: c++ unary-operator

  

可能重复:
  Multiple increment operators in single statement
  Undefined Behavior and Sequence Points

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

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

输出:

-1,0,0,0;

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

谢谢!

2 个答案:

答案 0 :(得分:6)

该代码的行为未定义。允许实现在i++之前或之后评估--i,或者错开评估,以使最终结果看起来毫无意义。

当面对诸如

之类的代码时,优化器甚至是合法的
if( k != 0 ) {
   cout << i++ << --i;
}
foofum(k);

理由因为 then分支中的代码是未定义的行为,然后我们可以得出结论k总是为零,并减少整个事物到

foofum(0);

(这可以通过以下事实得到正式证明:i的未定序更新的“未定义”行为恰好可能恰好将0分配给k并跳转到右大括号。意味着什么都可以发生。)

不要写那样的代码。

编辑:在一个现在删除的答案中建议,语句的效果仅仅是未指定的,因为重载的<<是函数调用而不是本机运算符。但是,这只是使声明等同于我们目前的目的

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的关系式中尚未定义。

答案 1 :(得分:2)

C / C ++中函数参数的评估顺序为未指定
参数传递给<<的顺序在这里是未指定的,因此是结果。