- 论坛徽章:
- 0
|
i = i++ + 1 !
别的论坛的,关于k = ++i + i++ * ++i; 的~~~~~~~
XX wrote:
>; i think the statement "k = ++i + i++ * ++i;" can be divide into several
>; steps : ++i;
>; ++i;
>; k=i+i*i;
>; i++;
First of all, this is the third time you've sent this message, I don't
really see what the point of repeating it so many times is.
Secondly, you cannot divide this expression into several steps. Your
code above assumes a certain ordering of evaluation for the
operations, and as I explained before, there is no such ordering. The
compiler is free to evaluate this expression however it wants. That is
what "undefined behavior" means.
The original statement results in undefined behavior. Your multi-step
process does not, however there is nothing that even remotely suggests
that the compiler will evaluate that expression in the manner you have
laid out.
The original expression has no sequence points. A sequence point is a
point in the execution of the code where all previous side effects
have completed, and no further side effects have begun computing. In
the original expression, there are no sequence points between the
multiple modifications of the variable i. This situation always
results in undefined behavior, and it is explicitly stated so in the
C++ standard.
Your multi-step expression has a sequence point in between each
portion of the expression, namely the end of the statement with a
semicolon. This provides a point for the compiler to ensure that all
side effects are complete before beginning the next operation.
For expressions like i++, the compiler can do this by storing a
temporary value, adding 1 to i, then using the stored value in the
resulting expression, or it could use i's value directly, and then
increment afterward. The sequence point gives the compiler a point by
which the side effect has to be completed before it can execute
further.
Without the sequence point, the compiler's execution of ++i and i++
could get severly botched, since it might be overwriting values it was
going to use to achieve the side effect or the expression's value.
This is a very important point to remember:
NEVER use multiple operations that have side effects on the same
object without a sequence point in between.
Doing so results in undefined behavior. The original expression above
is one example. Calling a function like foo(i++, i++) is another.
These are all bad practice and should be avoided like the plague.
Hope this helps clarify some of the confusion. |
|