59

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?

Ahmed Atia
  • 17,848
  • 25
  • 91
  • 133
  • 4
    And the moral of the story is to avoid writing that into production code :) – Robert Paulson Oct 22 '08 at 19:31
  • I totally agree with you, we should avoid writing this pieces of code into production code as Jon said, many incorrect answers, this may cause many problems during any project. – Ahmed Atia Oct 23 '08 at 10:18
  • 1
    Note that in C and C++, both of these output 11. It all relies on whether the compiler does the assignment first or the post-increment first. C and C++ do assignment first and post-increments after the assignment. – Alain Aug 24 '11 at 13:15
  • 1
    @Alain I'm sorry Alain, but you're wrong. The output is 10 and 11 in C++ with g++. – Zaid Khan Apr 24 '16 at 13:33
  • tbh it is a undefined expression. But you're wrong still. :) – Zaid Khan Apr 24 '16 at 13:35

11 Answers11

78

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);
}
Brian R. Bondy
  • 339,232
  • 124
  • 596
  • 636
  • 3
    x = ++x seems pretty useless, i don't particularly see a reason for either of those constructs... just x++ or ++x .. or what about x = x + ((Ceiling (Abs(x) + 1))/(Ceiling (Abs(x) + 1))) that should work too – stephenbayer Oct 22 '08 at 15:47
  • 5
    agreed, but I think the question was just asking why it reacts like that. – Brian R. Bondy Oct 22 '08 at 15:53
  • 5
    First phrase is wrong, x++ it will first return the value and afterwards increment - whereas ++x will first increment, than return the value. – Oliver Friedrich Dec 15 '08 at 11:38
57

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#.

tvanfosson
  • 524,688
  • 99
  • 697
  • 795
Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • That sounds strange to me... my impression is that the change should've been applied already by the time x hits Console.Writeline – Jon Limjap Oct 22 '08 at 14:41
  • The problem is the difference between pre-fix and -post-fix. x++ and ++x behave differently. – jjnguy Oct 22 '08 at 14:44
  • The change was applied but lost in the assignment. If you either use y = x++ instead or if you do x = ++x; the first example will output 11 as well. – Vinko Vrsalovic Oct 22 '08 at 14:44
  • x is incremented, then set back to 10 (which is the evaluated value of x++) - it's not that it's delayed until after Console.WriteLine. – Jon Skeet Oct 22 '08 at 14:44
  • Jon, you're really doing the Work Of The Lord in this thread. ;-) SO needs a badge to reward this kind of thorough commenting. I believe your comments in this thread are more valuable than my meagre reply. – Konrad Rudolph Oct 22 '08 at 14:51
  • 1
    Just trying to keep the misinformation appropriately corrected :) Unfortunately I need to go out now. But hey, I'd have written an answer if the existing correct ones such as yours didn't already do a great job! – Jon Skeet Oct 22 '08 at 14:52
17

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.

Zaid Khan
  • 786
  • 2
  • 11
  • 24
Vincent Ramdhanie
  • 102,349
  • 23
  • 137
  • 192
11
x = 10
x = ++x 

x would end up equalling 11.

AquaGeneral
  • 155
  • 1
  • 19
rp.
  • 17,483
  • 12
  • 63
  • 79
8
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).

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
Chris Marasti-Georg
  • 34,091
  • 15
  • 92
  • 137
  • Using your logic, then ++x ; does the following x = x+1; int returnValue = x; return returnValue; i.e. swapping lines 1 and 2 – john Jan 02 '20 at 14:53
  • 1
    I think this is the best answer, and closest to the 'behind-the-scenes' assembly language that implements the postfix increment – john Jan 02 '20 at 14:57
4

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.

Juan Pablo Califano
  • 12,213
  • 5
  • 29
  • 42
  • This looks like the best explanation. The order actually makes sense here. Also easy to implement using java script, open a web browser console by pressing F-12 with Chrome or Firefox (remember to use Shift+Enter for multi-lines). – john Jan 02 '20 at 13:41
  • Question can you switch the order of 1) and 2)? – john Jan 02 '20 at 14:07
1

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!

galois
  • 825
  • 2
  • 11
  • 31
1

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 ; ?

Max
  • 11
  • 1
0

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

0

Maybe I am not right, but it's easier for me to understand the result on a similar example:

public static void main(String[] args) {
    int x = 10;
    int y = 0;
    y = x + x++;  //1, 2, 3, 4
    x += x;       //5
    System.out.println("x = " + x + "; y = " + y);  //6
}

Let's take a look at operation y = x + x++ step by step:

  1. A computer takes the value of x and add it to value of x (10 + 10 = 20)
  2. The computer PUTS THE RESULT TO A TEMPORARY VARIABLE (temp = 20)
  3. The coputer increments x (10 + 1 = 11)
  4. The computer ASSIGNS THE RUSULT OF THE RIGHT SIDE OPERATION STORED IN temp to variable y (20)
  5. A computer takes the value of x and add it to value of x (11 + 11 = 22)
  6. The final result is: x = 22; y = 20

And now let's return to the our example and make the same steps:

public static void main(String[] args) {
    int x = 10;
    x = x++; //1, 2, 3, 4
    System.out.println(x);  //5
}
  1. A computer takes the value of x (10)
  2. The computer PUTS THE RESULT TO A TEMPORARY VARIABLE (temp = 10)
  3. The coputer increments x (10 + 1 = 11)
  4. The computer ASSIGNS THE RUSULT OF THE RIGHT SIDE OPERATION STORED IN temp to variable x (10)
  5. The final result is: x = 10
Matt Raines
  • 4,149
  • 8
  • 31
  • 34
vitaliy4us
  • 483
  • 5
  • 21
-4

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

Sundar R
  • 13,776
  • 6
  • 49
  • 76
  • It's very well-defined in C#, which is generally a saner language than C or C++ when it comes to this kind of thing. – Jon Skeet Oct 22 '08 at 14:42
  • 3. the old value is now assigned to x for the assignment Why the old value, not the value afetr it's incremented? – Ahmed Atia Oct 22 '08 at 14:43
  • Because the value of a post-increment expression is the result before it was incremented. – Jon Skeet Oct 22 '08 at 14:49