When I shift a bit field in an expression small bit fields behave one way and large bit fields another. I'm using gcc 5.3.0 on Arch Linux:
$ gcc --version gcc (GCC) 5.3.0 Copyright (C) 2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. I've created the following example: #include <stdio.h> struct fields { long long unsigned f0:12; long long unsigned f1:52; } __attribute__((__packed__)); struct fields x = { .f0 = 0xFFF, .f1 = 0xFFFFFFFFFFFFF }; long long unsigned g0; long long unsigned g1; void main(void) { g0 = x.f0 << 1; g1 = x.f1 << 1; printf("x.f0=0x%llx\n", x.f0); printf(" g0=0x%llx expect 0x1ffe\n", g0); printf("x.f1=0x%llx\n", x.f1); printf(" g1=0x%llx expect 0x1ffffffffffffe\n", g1); } The output is: $ gcc -m64 main.c -o main ; ./main x.f0=0xfff g0=0x1ffe expect 0x1ffe x.f1=0xfffffffffffff g1=0xffffffffffffe expect 0x1ffffffffffffe As you can see when shifting the f0, which is 12 bits, the most significant bit it is seen in the result. But when shifting f1, which is 52 bits, it is lost. Looking at the generated code the difference in output is because in g0 = x.f0 << 1 the and operation is done before the "shift left" using add %eax, %eax. Where as with g1 = x.f1 << 1 the and operation is done after the "shift left" using add %rax, %rax". 0000000000400506 <main>: 400506: 55 push %rbp 400507: 48 89 e5 mov %rsp,%rbp 40050a: 0f b7 05 f7 04 20 00 movzwl 0x2004f7(%rip),%eax # 600a08 <x> 400511: 66 25 ff 0f and $0xfff,%ax 400515: 0f b7 c0 movzwl %ax,%eax 400518: 01 c0 add %eax,%eax 40051a: 48 98 cltq 40051c: 48 89 05 fd 04 20 00 mov %rax,0x2004fd(%rip) # 600a20 <g0> 400523: 48 8b 05 de 04 20 00 mov 0x2004de(%rip),%rax # 600a08 <x> 40052a: 48 c1 e8 0c shr $0xc,%rax 40052e: 48 01 c0 add %rax,%rax 400531: 48 ba ff ff ff ff ff movabs $0xfffffffffffff,%rdx 400538: ff 0f 00 40053b: 48 21 d0 and %rdx,%rax 40053e: 48 89 05 d3 04 20 00 mov %rax,0x2004d3(%rip) # 600a18 <g1> It feels wrong that they would behave differently, is this really correct behavior? -- Wink