x+=x++;

2004/08/31

Tags: C#

Today I was looking through an internal C# user group list. One of the messages was about x+=x++; and what should be the right behavior. I thought this is more generally interesting, so I decided to blog it. But first, DO NOT WRITE THAT CODE!!!

Ok, with that out of the way, we can start…

Let’s take this code as an example:

int x = 3;

x += x++;

The first thing the compiler does whenever it sees something like z += y is to convert it to z = z + y. This is obviously true for +=, -=, *=, and /=. Ok, this was easy. Now we have just to consider:

x= x + x++;

This, by the way, gives the same result as:

x = x + x;

This, by the way, gives a different result from:

x = x++ + x;

This, by the way gives the same result as:

x = x + ++x;

As maddening as this may seem, it actually makes sense (once you understand how it works). But first, what is the difference between x++ and ++x? x++ returns the value of x to the current expression and then increments x. ++x increments x and then return its value to the current expression. Given this factoid (and knowing that c# evaluates expressions left to right), we can then consider what happens in the following case:

int x = 3;

x = x + x++;

Here is how the compiler conceptually evaluates it:

  1. x = (x) + x++ -> the first x gets evaluated and returns 3, x = 3
  2. x = 3 + (x)++ -> x gets evaluated and returns 3, x = 3
  3. x = 3 + (x++) -> x++ gets evaluated and x is incremented (to 4), x = 4
  4. x = (3 + 3) -> 3 + 3 gets evaluated and returns 6, x = 4
  5. (x = 6) -> x is assigned to 6 (overriding the previous value of 4)

Now let’s see how this one works:

int x = 3;

x = x++ + x;

  1. x = (x)++ + x -> x gets evaluated and returns 3, x =3
  2. x = (x++) + x -> x++ gets evaluated and x is incremented, x=4
  3. x = 3 + (x) -> x gets evaluated and returns 4, x = 4
  4. x = 3 + 4 -> 3+4 gets evaluated and returns 7, x = 4
  5. (x=7) -> x is assigned to 7 (overriding the previous value of 4)

Now let’s get to this one:

int x = 3;

x = x + ++x;

  1. x = (x) + ++x -> x gets evaluated and returns 3, x=3
  2. x = 3 + (++x) -> ++x gets evaluated and x is incremented, x=4
  3. x = 3 + (x) -> x gets evaluated and returns 4, x=4
  4. x = 3 + 4 -> 3+4 gets evaluated and returns 7, x = 4
  5. (x=7) -> x is assigned to 7 (overriding the previous value of 4)

I hope this is clear. By the way, in c++ the behavior for this expression is undefined…

But now… why did we make this legal? Why not err or warn at compilation time? Well…

Does it matter which of the previous options is the correct one? Not really because…

YOU ARE NOT GOING TO WRITE THAT CODE J

comments powered by Disqus Updated: 2019-01-23 11:41:32 +0100 +0100, Version: 6668e21