Jens Kilian wrote: > Consider the following test program: > --8<------------------------------------------------8<--- > #include <stdint.h> > #include <stdio.h> > > typedef enum { > FOO = 1LL << 0, > BAR = 1LL << 1, > BAZ = 1LL << 63 > } Foo; > > int > main(void) > { > uint64_t zip = (FOO << 32) | BAR; > uint64_t qux = ((Foo)FOO << 32) | BAR; > printf("%llx %llx\n", zip, qux); > return 0; > } > --8<------------------------------------------------8<--- > > This causes different behavior in GCC 3.2.3 (i386) vs. 4.1.2 (x86_64): > > ~ % gcc -v > Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2.3/specs > Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --host=i386-redhat-linux > Thread model: posix > gcc version 3.2.3 20030502 (Red Hat Linux 3.2.3-54) > ~ % gcc -o foo foo.c > ~ % ./foo > 100000002 100000002 > > ~ % gcc -v > Using built-in specs. > Target: x86_64-redhat-linux > Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-libgcj-multifile --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --with-cpu=generic --host=x86_64-redhat-linux > Thread model: posix > gcc version 4.1.2 20070626 (Red Hat 4.1.2-14) > ~ % gcc -o foo foo.c > foo.c: In function 'main': > foo.c:13: warning: left shift count >= width of type > ~ % ./foo > 2 100000002 > > Apparently GCC 4.1.2 converts the value of FOO to 32 bits before doing the > shift; the bizarre thing is that casting to Foo (which should be unnecessary) > avoids this. > > Is this a GCC bug, or does the standard really require this conversion? It's a bug. C99 says an enumerated type shall be large enough to represent all its members, and that when promoting the rank of the enumerated type shall equal the rank of the compatible integer type. Andrew.