Disassembly of the running code:
int i = 0;
xor edx, edx
mov dword ptr i, edx // set i = 0
i += i++;
mov eax, dword ptr i // set eax = i (=0)
mov dword ptr tempVar1, eax // set tempVar1 = eax (=0)
mov eax, dword ptr i // set eax = 0 ( again... why??? =\ )
mov dword ptr tempVar2, eax // set tempVar2 = eax (=0)
inc dword ptr i // set i = i+1 (=1)
mov eax, dword ptr tempVar1 // set eax = tempVar1 (=0)
add eax, dword ptr tempVar2 // set eax = eax+tempVar2 (=0)
mov dword ptr i, eax // set i = eax (=0)
Equivalent code
It compiles to the same code as the following code:
int i, tempVar1, tempVar2;
i = 0;
tempVar1 = i; // created due to postfix ++ operator
tempVar2 = i; // created due to += operator
++i;
i = tempVar1 + tempVar2;
Disassembly of the second code (just to prove they are the same)
int i, tempVar1, tempVar2;
i = 0;
xor edx, edx
mov dword ptr i, edx
tempVar1 = i; // created due to postfix ++ operator
mov eax, dword ptr i
mov dword ptr tempVar1, eax
tempVar2 = i; // created due to += operator
mov eax, dword ptr i
mov dword ptr tempVar2, eax
++i;
inc dword ptr i
i = tempVar1 + tempVar2;
mov eax, dword ptr tempVar1
add eax, dword ptr tempVar2
mov dword ptr i, eax
Opening disassembly window
Most people don't know, or even don't remember, that they can see the final in-memory assembly code, using Visual Studio Disassembly window. It shows the machine code that is being executed, it is not CIL.
Use this while debuging:
Debug (menu) -> Windows (submenu) -> Disassembly
So what is happening with postfix++?
The postfix++ tells that we'd like to increment the value of the operand after the evaluation... that everybody knows... what confuses a bit is the meaning of "after the evaluation".
So what does "after the evaluation" means:
- other usages of the operand, on the same line of code must be affected:
a = i++ + i
the second i is affected by the increment
Func(i++, i)
the second i is affected
- other usages on the same line respect short-circuit operator like
||
and &&
:
(false && i++ != i) || i == 0
the third i is not affected by i++ because it is not evaluated
So what is the meaning of: i += i++;
?
It is the same as i = i + i++;
The order of evaluation is:
- Store i + i (that is 0 + 0)
- Increment i (i becomes 1)
- Assign the value of step 1 to i (i becomes 0)
Not that the increment is being discarded.
What is the meaning of: i = i++ + i;
?
This is not the same as the previous example. The 3rd i
is affected by the increment.
The order of evaluation is:
- Store i (that is 0)
- Increment i (i becomes 1)
- Store value of step 1 + i (that is 0 + 1)
- Assign the value of step 3 to i (i becomes 1)
i
once and the postfix increments last. To get 1, you have to use the prefix. – Veradiai++
aloud? I advice you to always read it as 'i POSTINCREMENT' inside your head, rather then 'i plus plus'. :) – Towersi
on the left-hand side of+=
is "cached" before the right-hand side is evaluated. This is counter-intuitive, as it would, for instance, require a copy operation ifi
were an object. (Please do not mis-understand me: I absolutely agree to stating that0
is the correct and standard-conforming answer.) – Potomaci += i++;
was intended to do, I guarantee there's a simpler and clearer way to do it. – Averii
in thefor
loop would start at 1 (you could seti = -1
or usei-1
inside your loop logic, but I think most find that looks strange). So we usei++
and I believe the misunderstanding comes from that usage. – Hypophosphite