I heard that C compiler with/without optimization option may generate different program(compiling the program with optimizations causes it to behave differently), but I never encountered such case. Anyone can give simple example to show this?
For gcc 4.4.4, this differs with -O0
and -O2
void foo(int i) {
foo(i+1);
}
main() {
foo(0);
}
With optimizations this loops forever. Without optimizations, it crashes (stack overflow!)
Other and more realistic variants would typically be dependent on timing, vulnerable to float exactness variations, or depending on undefined behavior (uninitialized variables, heap/stack layout)
If you look at the assembly generated by this code :
int main ()
{
int i = 1;
while (i) ;
return 0;
}
Whitout the -O2 flag :
.file "test.c"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
subl $16, %esp
movl $1, -4(%ebp)
.L2:
cmpl $0, -4(%ebp)
jne .L2
movl $0, %eax
leave
ret
.size main, .-main
.ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
.section .note.GNU-stack,"",@progbits
With the -O2 flag :
.file "test.c"
.text
.p2align 4,,15
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
.L2:
jmp .L2
.size main, .-main
.ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
.section .note.GNU-stack,"",@progbits
With the -O2 flag, the declaration of i
and the return value are ommited and you only have a label with a jump on this same label to constitute the infinite loop.
Without the -O2 flag, you can clearly see the allocation of the i
space on the stack (subl $16, %esp
) and initialization (movl $1, -4(%ebp)
) as well as the evaluation of the while condition (cmpl $0, -4(%ebp)
) and the return value of the main function (movl $0, %eax
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With