I didn't realize the code violated strict aliasing. After reading it, it seems trivial. Somehow I also thought this is only a C++ thing. Apparently this is "defined as undefined behavior" in C99?
Thanks a lot! You just found a bug in my code. Regards, Thanks, Hendrik Greving On Wed, Oct 2, 2013 at 3:19 AM, Mikael Pettersson <mikpeli...@gmail.com> wrote: > 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; > > }