对一元运算如何产生此输出感到困惑
可能的重复:
单个语句中的多个增量运算符
未定义的行为和序列点
有人可以向我解释一下为什么这行代码会生成这样的输出? 代码(将 i 和 j 都初始化为零后):
cout<<i++<<','<<++j<<','<<--i<<','<<j--<<'\n';
输出:
-1,0,0,0;
我知道 i++ 意味着先评估然后增加 1,而 ++i 意味着增加 1 然后评估。但不确定顺序 cout 语句中的多重求值是什么行为。
谢谢!
Possible Duplicates:
Multiple increment operators in single statement
Undefined Behavior and Sequence Points
can someone explain to me why this line of code generate such output?
code (after initilizeing both i&j to zero):
cout<<i++<<','<<++j<<','<<--i<<','<<j--<<'\n';
output:
-1,0,0,0;
I know i++ means evaluate first then increase by 1, while ++i means increase by 1 then evaluate. but not sure what behavior is the multiple evaluation in a sequenced cout statement.
thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
该代码的行为未定义。允许实现在
--i
之前或之后评估i++
,或者交错评估,使得最终结果看起来毫无意义。对于优化器来说,这甚至是合法的,当遇到诸如
推理这样的代码时,因为 then 分支中的代码是未定义的行为,那么我们可以得出结论:
k
始终为零,并将整个事情减少到(这将通过以下事实得到正式证明:对
i
的未排序更新的“未定义”行为可能碰巧将 0 分配给k
和跳跃到右大括号。未定义确实意味着任何事情都可能发生)。只是不要编写这样的代码。
编辑:在现已删除的答案中建议,该语句的效果只是未指定,因为重载的
<<
是函数调用而不是本机运算符。然而,就我们当前的目的而言,这只是使该语句等效于(这里
f
表示单参数ostream::operator<<()
,但AAA.f(BBB)
和f(AAA,BBB)
的评估顺序规则相同)。编译器可以决定计算f
参数的顺序。如果它碰巧首先评估i--
,则评估顺序变为:i--
i++
g
f
由于没有序列点分隔
i--
和i++
,因此会导致未定义的行为。另一方面,f(g(i+=h()), i++) 可以说只是在序列点形式主义下未指定。我认为它在 C++1x 的关系公式中恢复为未定义。
The behavior of that code is undefined. An implementation is allowed to evaluate
i++
before--i
, or after it, or to stagger the evaluations such that the end results seem to make no sense at all.It's even legal for an optimizer, when faced with code such as
to reason that because the code in the then branch is undefined behavior, then we can conclude that
k
is always zero, and reduce the entire thing to(This would be formally justified by the fact that the "undefined" behavior of the unsequenced updates to
i
just might happen to be assigning 0 tok
and jumping to the closing brace. Undefined really does mean anything can happen).Just don't write code like that.
Edit: It was suggested in a now-deleted answer that the effect of the statement is merely unspecified because the overloaded
<<
's are function calls rather than native operators. However, that just makes the statement equivalent, for our present purposes, to(here the
f
represents a one-argumentostream::operator<<()
, but the rules for evaluation order forAAA.f(BBB)
andf(AAA,BBB)
are the same). The compiler can decide in which order it evaluates the arguments tof
. If it happens to evaluatei--
first, the evaluation order becomes:i--
i++
g
f
Since there is no sequence point separating
i--
andi++
, undefined behavior results.On the other hand,
f(g(i+=h()), i++)
is arguably merely unspecified under the sequence-point formalism. I think it reverts to undefined in C++1x's relational formulation.C/C++ 中函数参数的计算顺序是未指定。
此处未指定参数传递给
<<
的顺序,因此结果也是如此。The order of evaluation of arguments to a function in C/C++ is Unspecified.
The order in which arguments are being passed to
<<
is Unspecified here and hence the result.