Hendrik Greving writes:
 > gcc --version
 > gcc (GCC) 4.8.1
 > 
 > (4.7.2 seems to work)
 > 
 > gcc -g -fPIC -O2 -Wall -o test test.c
 > 
 > ./test
 > type_a is 0x0
 > 
 > Correct would be 0x14000. I don't see how the C-code could be
 > ambiguous, I think this is a bug?
 > 
 > test.c:
 > 
 > #include <stdio.h>
 > 
 > typedef struct
 > {
 >     unsigned int a:4;
 >     unsigned int b:5;
 >     unsigned int c:5;
 >     unsigned int d:18;
 > } my_comb_t;
 > 
 > struct my_s
 > {
 >     int l;
 > };
 > 
 > my_comb_t *getps_f (struct my_s *a);
 > 
 > #define GETPS(x) getps_f(&(x))
 > 
 > my_comb_t *
 > getps_f (struct my_s *a)
 > {
 >   my_comb_t *p = (my_comb_t *) &(a->l);
 >   return p;

This is where the test case is wrong.  You need to use a union so that
gcc can see the type punning, or compile with -fno-strict-aliasing.

Without -fno-strict-aliasing I see different results for -m32 vs -m64,
but not across gcc versions; with -fno-strict-aliasing all results match.

 > }
 > 
 > int g_modes = 5;
 > 
 > int main(void)
 > {
 >     int modes = g_modes;
 >     int type_a = 0;
 > 
 >     if (modes)
 >     {
 >         struct my_s m;
 >         m.l = type_a;
 >         my_comb_t *p = GETPS(m);
 >         p->d |= modes;
 >         type_a = m.l;
 >     }
 >     printf("type_a is 0x%x\n", type_a);
 >     return 0;
 > }

Reply via email to