John David Anglin wrote:
#include <stdio.h> unsigned char T (unsigned char x) { static int first = 1; static unsigned char firstx;if (first) { first = 0; firstx = x; return ~x; } if (x == firstx) printf ("Behavior is pre GCC 4.0\n"); else printf ("Behavior is GCC 4.0 and later\n"); return 0; } *** cut *** extern int T (unsigned char); int foo (void) { int result; unsigned char x; result = T (x); T (x); return result; } int main () { return foo (); } Compile as follows: gcc-3.4 -O2 -c T.c gcc-3.4 -o und -O2 und.c T.o ./und Behavior is pre GCC 4.0 gcc-4.0 -o und -O2 und.c T.o Behavior is GCC 4.0 and later That's what I see on hppa-unknown-linux-gnu. The 4.0 behavior is caused by GCC using result for the second call to T, whereas 3.3 and 3.4 use the same undefined value for both calls to T.
My understanding (which I am not 100% confident of, would be happy to have some people more expert than me in the C standard) is that since X is still indeterminate in the comparison, the result of the comparison is undefined At AdaCore, looking at customer reports, we often find that reported optimization bugs are in fact just manifestations of bugs in the program, and indeed it can often be complex to figure this out. We really really ought to have a switch to initialize everything by default, then you can tell immediately if something like this is due to uninitialized variables. However, an interesting issue is whether this behavior is valid for Ada, I am a little dubious (the Ada standard is much stricter about the effect of uninitialized variables). But it may still be OK, needs careful analysis. Apologies to John Anglin who I know worked hard to figure out what was going on here, but we do need to know whether something is a bug before we go fixing it! Robert Dewar
