What's the difference between X = X++; vs X++;?

Viewed 50940

Have you ever tried this before?

static void Main(string[] args)
{
    int x = 10;
    x = x++;
    Console.WriteLine(x);
}

Output: 10.

but for

static void Main(string[] args)
{
    int x = 10;
    x++;
    Console.WriteLine(x);
}

Output: 11.

Could anyone explain why this?

11 Answers

X++ will increment the value, but then return its old value.

So in this case:

static void Main(string[] args)
{
    int x = 10;
    x = x++;
    Console.WriteLine(x);
}

You have X at 11 just for a moment, then it gets back to 10 because 10 is the return value of (x++).

You could instead do this for the same result:

static int plusplus(ref int x)
{
  int xOld = x;
  x++;
  return xOld;
}

static void Main(string[] args)
{
    int x = 10;
    x = plusplus(x);
    Console.WriteLine(x);
}

It is also worth mentioning that you would have your expected result of 11 if you would have done:

static void Main(string[] args)
{
    int x = 10;
    x = ++x;
    Console.WriteLine(x);
}

In the assignment x = x++ you first extract the old value of x to use in evaluating the right-hand side expression, in this case 'x'; then, you increment x by 1. Last, you assign the results of the expression evaluation (10) to x via the assignment statement.

Perhaps an equivalent code would make the predicament clear:

var tmp = x;
x++;
x = tmp;

This is the equivalent of your x = x++ code in C#.

The behaviour of x++ is to increment x but return the value before the increment. Its called a post increment for this reason.

So x = x++; simply put will

1. return the value, then

2. increment x, then

3. assign the original value(returned in step 1) of x to x.

x = 10
x = ++x 

x would end up equalling 11.

x++;

does the following:

int returnValue = x;
x = x+1;
return returnValue;

As you can see, the original value is saved, x is incremented, and then the original value is returned.

What this ends up doing is saving the value 10 somewhere, setting x equal to 11, and then returning 10, which causes x to be set back to 10. Note that x does actually become 11 for a few cycles (assuming no compiler optimization).

You can think of it like this:

int x = 10;

X is a container, and contains a value, 10.

x = x++;

This can be broken down to:

1) increment the value contained in x 
    now x contains 11

2) return the value that was contained in x before it was incremented
    that is 10

3) assign that value to x
    now, x contains 10

Now, print the value contained in x

Console.WriteLine(x);

And, unsurprisingly, it prints out 10.

The first thing you do is called "post-increment" meaning that

    int x = 10;
    x++; //x still is 10
    Console.WriteLine(x); //x is now 11(post increment)

so the moment you assign x = x++; x still is 10 what you could do, if you need x to be 11 at this line write ++x (think its called pre increment correct me if im wrong) ... alternatively right x++; and than x = x++;

question, is it dependend on the line or on statement meaning that it will increment after the ; ?

I know there are a lot of answers, and an accepted one, but I'll still put in my two cents for yet another point of view.

I know this question was C#, but I assume that for something like a postfix operator it doesn't have different behavior than C:

int main(){
    int x = 0;
    while (x<1)
        x = x++;
}

The assembly (yes, I edited it to make it more readable) generated by the compiler shows

...
    mov    -8(rbp), 0       ; x = 0
L1:
    cmp    -8(rbp), 1       ; if x >= 1,
    jge    L2               ;     leave the loop
    mov    eax, -8(rbp)     ; t1 = x
    mov    ecx, eax         ; t2 = t1
    add    ecx, 1           ; t2 = t2 + 1
    mov    -8(rbp), ecx     ; x  = t2 (so x = x + 1 !)
    mov    -8(rbp), eax     ; x  = t1 (kidding, it's the original value again)
    jmp    L1
L2:
...

Equivalently, the loop is doing something like:

t = x
x = x + 1
x = t

Side note: turning on any optimizations gives you some assembly result like this:

...
L1:
    jmp    L1
...

it doesn't even bother to store the value you told it to give x!

Putting the increment operator after the variable means that the increment and assignment happens after the expression is evaluated... so The original statement x = x++; translates to 1. Evaluate x and store value in tyransient memory ... Now execute code called for by ++ operator .... (steps 2 & 3) 2. Increment value of x (in transient memory) 3. Assign Incremented value to x's storage location ... Now, continue with rest of the line's execution, to the left, there's an = sign... 5. So assign value stored in Step 1 (unincremented value) to expression on left of = sign... which is x

The result of the assignment

x = x++;

is undefined in C and C++, and I would guess the same with C# too.

So, the actual sequence of operations that occurs depends on how the compiler decides to implements it, there's no guarantee whether the assignment or the increment will occur first. (this is well defined in C#, as Jon Skeet has pointed out in the comments. Though I now feel this answer is of much less value now, I'm keeping this post undeleted for the OP's question and its answer in the comments.)

However, in this case, it appears the sequence of operations that happens is:

  1. the old value (10) of x is saved
  2. x is incremented for the ++ part
  3. the old value is now assigned to x for the assignment

In this way, though the increment occurs, it is overtaken by the assignment with old value, thus keeping x at 10.

HTH

Related