long bit-fields with g++ 4.4.1

Cedric Roux cedric.roux@acri-st.fr
Fri Mar 12 13:49:00 GMT 2010


Vineet Soni wrote:
> The integral promotion behavior of long bit-fields has changed with g++ 4.4.1 on
> x86_64-linux, and appears broken.  Consider:
> 
> #include <stdio.h>
> #define T unsigned long
> int main()
> {
>   struct { T f : 33; } s = { 1UL << 32 };
>   printf("%lx %lx %lx\n", (T)s.f, (T)(s.f << 1), (T)((s.f << 1) >> 1));
> 
>   struct { T f : 16; } t = { 1UL << 15 };
>   printf("%lx %lx %lx\n", (T)t.f, (T)(t.f << 17), (T)((t.f << 17) >> 17));
> 
>   return 0;
> }
> 
> Based on my interpretation of the C++ standard, the expected output is:
> 
>     100000000 200000000 100000000
>     8000 100000000 8000
> 
> The actual output is:
> 
>     $ g++-4.4.1 -Wall -pedantic x.c; ./a.out
>     100000000 200000000 100000000
>     8000 0 0
> 
> Is this a bug?
> 
> Note that 4.0.2 matches the expected output:
> 
>     $ g++-4.0.2 -Wall -pedantic x.c; ./a.out
>     100000000 200000000 100000000
>     8000 100000000 8000

If that is what you refer to:
3 An  rvalue for an integral bit-field (_class.bit_) can be converted to
  an rvalue of type int if int can represent all the values of the  bit-
  field;  otherwise, it can be converted to unsigned int if unsigned int
  can represent all the values of the bit-field.  If  the  bit-field  is
  larger yet, no integral promotion applies to it.  If the bit-field has
  an enumerated type, it is treated as any other value of that type  for
  promotion purposes.
(found on the internet, I don't have the standard)

we can understand that "t" may be promoted to "int" (which is 32b) because
it occupies 16 bits. And the << arithmetic operator asks for the
promotion.

Maybe that's why you have 0.
Maybe that's the way it has to be and gcc 4.0.2 was wrong.

Note that doing:
   printf("%lx %lx %lx\n", (T)t.f, (T)((unsigned long)t.f << 17), (T)(((unsigned long)t.f << 17) >> 17));
prints what you wait (not 0)
(with a g++ 4.3.2, not even 4.4.1)

(Note that I am not involved in g++ or gcc development nor
C++ standardization, so all what I say may be totally wrong.)



More information about the Gcc-help mailing list