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;
> }