A deep dive into a subtle C language bug involving bit-field integer promotions. When a bit-field is used in a shift expression, different compilers disagree on whether to promote it to signed or unsigned int. Microsoft compilers treat the bit-field as its declared base type (unsigned), while gcc and clang consider the bit-field width and promote narrow unsigned bit-fields to signed int. This divergence stems from ambiguous wording in C99 that was only partially clarified in C11. A compiler survey across 16-bit, 32-bit, and 64-bit compilers confirms the split: all 16-bit compilers and all Microsoft compilers keep the unsigned type, while IBM VisualAge, gcc, and clang promote to signed int. The result is silent, compiler-dependent behavior with no warnings emitted.

Sort: