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.

Reply via email to