This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Manipulating bit fields is behaving inconsistently


Hi,

> struct fields {
>   long long unsigned f0:12;
>   long long unsigned f1:52;
> } __attribute__((__packed__));

the C99 standard ISO/IEC 9899 forbids this type:

6.7.2.1 Structure and union specifiers

4 A bit-field shall have a type that is a qualified or unqualified version of _Bool, signed int,
   unsigned int, or some other implementation-defined type.

The C standard simply does not promote the bit-field value to any type larger than int or
unsigned int.

GCC chooses to do the larger than int computations in an artificial 52-bit type, but it is a
non-standard extension.

And if you compile your example with -Wall you'll see the problem:

gcc -m32 -O3 -Wall  test.c
test.c: In function 'main':
test.c:17:21: warning: format '%llx' expects argument of type 'long long unsigned int', but argument 2 has type 'int' [-Wformat=]
   printf("x.f0=0x%llx\n", x.f0);
                     ^
test.c:19:21: warning: format '%llx' expects argument of type 'long long unsigned int', but argument 2 has type 'long long unsigned int:52' [-Wformat=]
   printf("x.f1=0x%llx\n", x.f1);
                     ^

so especially the first warning is no joke:

./a.out 
x.f0=0x80497b400000fff
  g0=0x1ffe expect 0x1ffe
x.f1=0xfffffffffffff
  g1=0xffffffffffffe expect 0x1ffffffffffffe


OTOH that is perfectly OK for C++:

gcc -x c++ -m32 -O3 -Wall  test.c

./a.out 
x.f0=0xfff
  g0=0x1ffe expect 0x1ffe
x.f1=0xfffffffffffff
  g1=0x1ffffffffffffe expect 0x1ffffffffffffe


Regards
Bernd.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]