Let's look at the intermediary language code for this:
IL_0000: nop IL_0001: ldc.i4.s 2A IL_0003: stloc.0
This loads the constant integer 42 onto the stack and then saves it in the variable c and immediately loads it onto the stack.
IL_0005: stloc.1 IL_0006: ldloc.1
This copies the value to another register and loads it again.
IL_0007: ldc.i4.1 IL_0008: add
This adds the constant 1 to the loaded value.
IL_0009: stloc.0
... and saves the result of (43) in the variable c .
IL_000A: ldloc.1 IL_000B: stloc.0
Then the value is loaded from another register (this is still 42!) And stored in the variable c .
IL_000C: ldloc.0
Then the value (42) is loaded from the variable and printed.
So what you can see from this is that while c++ increments the value of the variable by one after the result has been returned, this increase happens even before the value of the variable is set. So the sequence looks something like this:
- Get value from
c - Post increment
c - Assign previously read value
c
And that should explain why you get this result :)
To add another example, as it was mentioned in a comment that was deleted:
c = c++ + c;
This works very similarly: if you first enter the initial value of 2, the left side of the addition is evaluated first. Thus, the value is read from variable (2), then c increases ( c becomes 3). Then the right side of the addition is evaluated. The value of c is read (now 3). Then the addition takes place (2 + 3), and the result (5) is assigned to the variable.
The conclusion from this is that you should avoid mixing the increase and decrease operations in normal expressions. Although the behavior is very clearly defined and makes perfect sense (as shown above), it is still difficult to wrap your head around you. Especially when you assign something to the same variable that you are increasing in the expression, it gets confusing quickly. So do yourself and others a favor and avoid increment / decrement operations when they are not completely on their own :)