Re: 64-bit enums and left shift operator - invalid code or GCC bug?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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.

[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux