I searched for x++ vs ++x and I found a great answer here, So I decide to see the assembly output of gcc to see how x++ and ++x implemented:
main() { int s = 0; ++s; return 0; }
Compiling the example:
gcc mul.c -masm=intel -o mul.asm
Output of ++s:
.file "mul.c"
.intel_syntax
.text
.p2align 4,,15
.globl main
.type main, @function
main:
lea %ecx, [%esp+4]
and %esp, -16
push DWORD PTR [%ecx-4]
push %ebp
mov %ebp, %esp
push %ecx
sub %esp, 16
mov DWORD PTR [%ebp-8], 0
add DWORD PTR [%ebp-8], 1
mov %eax, 0
add %esp, 16
pop %ecx
pop %ebp
lea %esp, [%ecx-4]
ret
.size main, .-main
.ident "GCC: (GNU) 4.2.1 20070719 [FreeBSD]"
Output for x++:
.file "mul.c"
.intel_syntax
.text
.p2align 4,,15
.globl main
.type main, @function
main:
lea %ecx, [%esp+4]
and %esp, -16
push DWORD PTR [%ecx-4]
push %ebp
mov %ebp, %esp
push %ecx
sub %esp, 16
mov DWORD PTR [%ebp-8], 0
add DWORD PTR [%ebp-8], 1
mov %eax, 0
add %esp, 16
pop %ecx
pop %ebp
lea %esp, [%ecx-4]
ret
.size main, .-main
.ident "GCC: (GNU) 4.2.1 20070719 [FreeBSD]"
So, I am asking if x++ and ++x have different meaning, why GCC outputs the some assembly for them, shouldn't have different output?
This is an example of a not-well written test case. The actual result of the expression value++
or ++value
is never stored, as such the compiler can handle both equivalent for basic types.
Use this examples instead:
main() { int s = 0, x; x = ++s; return 0; }
main() { int s = 0, x; x = s++; return 0; }
(gdb) disas /m main Dump of assembler code for function main(): 1 int main(){ 0x0040138c : push %ebp 0x0040138d : mov %esp,%ebp 0x0040138f : and $0xfffffff0,%esp 0x00401392 : sub $0x10,%esp 0x00401395 : call 0x4018d4 2 int s = 0; 0x0040139a : movl $0x0,0xc(%esp) 3 int x; 4 x = s++; 0x004013a2 : mov 0xc(%esp),%eax 0x004013a6 : mov %eax,0x8(%esp) 0x004013aa : incl 0xc(%esp) 5 return 0; 0x004013ae : mov $0x0,%eax 6 } 0x004013b3 : leave 0x004013b4 : ret End of assembler dump. (gdb)
(gdb) disas /m main Dump of assembler code for function main(): 1 int main(){ 0x0040138c : push %ebp 0x0040138d : mov %esp,%ebp 0x0040138f : and $0xfffffff0,%esp 0x00401392 : sub $0x10,%esp 0x00401395 : call 0x4018d4 2 int s = 0; 0x0040139a : movl $0x0,0xc(%esp) 3 int x; 4 x = ++s; 0x004013a2 : incl 0xc(%esp) 0x004013a6 : mov 0xc(%esp),%eax 0x004013aa : mov %eax,0x8(%esp) 5 return 0; 0x004013ae : mov $0x0,%eax 6 } 0x004013b3 : leave 0x004013b4 : ret End of assembler dump. (gdb)