Reputation: 79
When using optimizations O2 and above with gcc I get unexpected output with the following code.
#include <stdio.h>
int f ( int *a, float *b ) {
*a = 1;
*b = 0;
printf ( "%d ", *a );
return *a;
}
int main ( ) {
int i = 0;
printf ( "%d\n", f ( &i, &i ) );
}
This code normally should print "0 0" but instead with -O2 is prints "1 0". Then if I remove the printf in the function f it just prints 1. That is the same printf statement having its output changed by a printline.
Why does this happen?
Also I am aware I should never be doing this, I just want to know why it's happening.
Upvotes: 0
Views: 63
Reputation: 224312
With both -O0
and -O2
, GCC 9.2 generates code that performs *a = 1;
first and *b = 0;
second.
In the unoptimized case, it then loads *a
from memory to pass it to printf
and to return it. Since i
was set to 0 by *b = 0;
, loading it as *a
produces 0, and that is what is printed and what is returned.
In the optimized case, the compiler assumes *a
and *b
are different objects and, therefore, that the *a = 1;
has set the value of *a
to 1, and that the *b = 0;
did not change it. Consequently, when passing *a
to printf
, it passes 1 without loading it from memory. (The 1 is hard-coded as an immediate operand in an instruction.)
Upvotes: 5