i = i++ doesn't increment i. Why? [duplicate]
Possible Duplicates:
Why does this go into an infinite loop?
Things like i = i++
have undefined behavior in C and C++ because the value of a scalar object is changes twice within the same expression without intervening sequence point.
However I suppose that these kind of expressions have well-defined behavior in C# or Java because AFAIK the evaluation of argument goes left to right and there are sequence points all over.
That said, I'd expect i = i++
to be equivalent to i++
. But it's not. The following program outputs 0
.
using System;
class Program
{
static void Main(string[] args)
{
int i = 0;
i = i++;
Console.WriteLine(i);
}
}
Could you help me understand why?
Disclaimer: I am fully aware that whether or not the behavior of above-mentioned constructs is defined, they are silly, useless, unreadable, unnecessary and should not be used in code. I am just curious.
The behavior is well defined in C# and the evaluation order is:
- Left side
i
is evaluated to the variablei
- Right side is evaluated to 0, and
i
is incremented (nowi==1
) - The assignment is executed, it sets
i
to 0. (nowi==0
)
The end result is i==0
.
In general you first create an expression tree. To evaluate it you evaluate first the left side, then the right side and finally the operation at the root. Do that recursively.
The result of the post-increment expression i++
is the original value of i
. So after i++
has been evaluated (incrementing i
), you assign the old value of i
to ... i
.
Just use
i++;
;)
i = ++i
is the code that does what you think is going on here. i++
actually behaves a bit differently.
With i++
, the value of i
is increased, but the value of i++
is not the new value of i
, it's the previous value. So when you do i = i++
, you're saying "increase the value of i
, then set i
to the old value".
Well, the right-hand side expression must be evaluated before the assignment can take place. Now, i++
will evaluate to the current value of i
, and i's value will subsequently increase by one. However, the assignment hasn't been performed yet, and when it is, it will overwrite the current value of i
(1) with whatever the rhs expression evaluated to, which in your case was 0.
The key difference is between ++i
(pre-increment, which evaluates to the new value of i
after incrementing) and i++
, or post-increment, which evaluates to the current value of i
before incrementing.
Had you used ++i
instead, the right-hand side expression would have evaluated to 1, resulting in i == 1.