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

Reply via email to