The comments at the top of the following source file describes the bug. This happens on gcc 4.1.0 too. for what it is worth, uname -a and gcc -v output for the Linux box I am currently using are at the end. The actual code is only 14 lines and only includes stdio.h.
/* source file: enum_bug.c * * An anomaly in gcc C: according to C99 6.7.2.2, enumeration constants * must have signed int type and, if some enumeration constant has * a negative value, then the integer type compatible with the * enumeration type must be a signed type. It seems to be possible * to fool gcc into misapplying these rules by making the type of * the integer constant expression giving the value of an enumeration * constant an unsigned integer type. This was first observed in a case * where the expression involved sizeof, but just a cast to unsigned or using * an unsigned integer constant has the same effect as seen below: * * This has been observed on various Linux PCs and on Mac OS X with * several versions of gcc (3.4.1 up to 4.1.0). * * Compiling and running with * gcc -o enum_bug enum_bug.c ; ./enum_bug * * produces no diagnostics and code that prints out the following: * (a < 0) = 1, (A2 < 0) = 1, A{1,2} = +0, -1 (b < 0) = 0, (B2 < 0) = 0, B{1,2} = +0, -1 * * Compiling and running with: * gcc -ansi -pedantic -o enum_bug enum_bug.c; ./enum_bug * * results in an an incorrect warning * enum_bug.c:38: warning: ISO C restricts enumerator values to range of `int' * * but with code that correctly prints out: * (a < 0) = 1, (A2 < 0) = 1, A{1,2} = +0, -1 (b < 0) = 1, (B2 < 0) = 1, B{1,2} = +0, -1 * * Rob Arthan (rda at lemma-one dot com) 19th December 2006 */ #include <stdio.h> enum A {A1 = 0, A2 = A1 - 1}; enum B {B1 = 0u, B2 = B1 - 1}; int main(void) { enum A a = -1; enum B b = -1; printf("(a < 0) = %d, (A2 < 0) = %d, A{1,2} = %+d, %+d\n", (int)(a < 0), (int)(A2 < 0), (int)A1, (int)A2); printf("(b < 0) = %d, (B2 < 0) = %d, B{1,2} = %+d, %+d\n", (int)(b < 0), (int)(B2 < 0), (int)B1, (int)B2); return 0; } /* * uname -a: Linux localhost 2.6.8.1-12mdk #1 Fri Oct 1 12:53:41 CEST 2004 i686 Pentium III (Coppermine) unknown GNU/Linux * gcc -v: Reading specs from /usr/lib/gcc/i586-mandrake-linux-gnu/3.4.1/specs Configured with: ../configure --prefix=/usr --libdir=/usr/lib --with-slibdir=/lib --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --enable-long-long --enable-__cxa_atexit --enable-clocale=gnu --disable-libunwind-exceptions --enable-languages=c,c++,ada,f77,objc,java --host=i586-mandrake-linux-gnu --with-system-zlib Thread model: posix gcc version 3.4.1 (Mandrakelinux 10.1 3.4.1-4mdk) */ -- Summary: Enumeration types and enumeration constants erroneously given unsigned types Product: gcc Version: 3.4.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: rda at lemma-one dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30260