int x = 10;
x += x--;
In C#/.Net, why does it equal what it equals? (I'm purposely leaving the answer out so you can guess and see if you're right)
int x = 10;
x += x--;
In C#/.Net, why does it equal what it equals? (I'm purposely leaving the answer out so you can guess and see if you're right)
Look at this statement:
x += x--;
This is equivalent to:
x = x + x--;
Which is equivalent to:
int a1 = x; // a1 = 10, x = 10
int a2 = x--; // a2 = 10, x = 9
x = a1 + a2; // x = 20
So x
is 20 afterwards - and that's guaranteed by the spec.
What's also pretty much guaranteed, although not by the spec, is that anyone using such code will be attacked by their colleagues. Yes, it's good that the result is predictable. No, it's not good to use that kind of code.
From the specs 7.13.2
If the return type of the selected operator is implicitly convertible to the type of x, the operation is evaluated as x = x op y, except that x is evaluated only once.
So your statement is equivalent to x = x + x--;
which is evaluated in left-to-right order and gives the answer 20.
Note that there is also a difference between --x
and x--
here. If you had written x += --x;
this would be equivalent to x = x + --x
; then you would get 19. This is because the value of x is decremented and the resulting value is used in the expression (unlike x--
where the original value of x is used in the expression).
This expression x = x + --x + x
will give 28 because the third timefourth time (see comments) x is evaluated it is 9.
20; the "--" doesn't happen until after everything gets evaluated, and that value is overwritten by the left-hand side of the equals.
The answer is 20. And Tom, you really aren't as surprised as your questions seems to imply, right? And to those of you who are assuming the answer is 19 - I think you're confused with x += --x;
Jon is of course right.
A good way to think about this is to remember:
1) subexpressions are always evaluated left to right. Period. Evaluation of a subexpression may induce a side effect.
2) execution of operators is always done in the order indicated by parentheses, precedence and associativity. Execution of operators may induce a side effect.
The "x" to the left of the += is the leftmost subexpression, and therefore rule (1) applies. Its value is computed first -- 10.
The x-- to the right of the += is the next one in left-to-right order, so it is evaluated next. The value of x-- is 10, and the side effect is that x becomes 9. This is as it should be, because -- is of higher precedence than +=, so its side effect runs first.
Finally, the side effect of += runs last. The two operands were 10 and 10, so the result is to assign 20 to x.
I get questions about this all the time. Remember, the rules are very straightforward: subexpressions left-to-right, operators in precedence order, period.
In particular, note that the commonly-stated reasoning "the -- operator is postfix and therefore runs after everything else" is incorrect reasoning. I discuss why that is incorrect in the articles below.
Here are some articles I've written on this subject:
http://blogs.msdn.com/ericlippert/archive/tags/precedence/default.aspx