C Bit-Field Pitfalls
fanf2
26 points
8 comments
March 21, 2026
Related Discussions
Found 5 related stories in 70.9ms across 3,471 title embeddings via pgvector HNSW
- Byte Interviews Chuck Peddle, Father of the MOS 6502 and Commodore PET (1982) rbanffy · 41 pts · March 28, 2026 · 52% similar
- BitNet: 100B Param 1-Bit model for local CPUs redm · 326 pts · March 11, 2026 · 51% similar
- Show HN: 1-Bit Bonsai, the First Commercially Viable 1-Bit LLMs PrismML · 182 pts · March 31, 2026 · 48% similar
- Never Bet Against x86 raphinou · 65 pts · March 06, 2026 · 47% similar
- Signing data structures the wrong way malgorithms · 92 pts · April 01, 2026 · 45% similar
Discussion Highlights (5 comments)
mwkaufma
tl;dr standard is unclear if they should respect the signed-ness of the declaration (MSCV), or always promote to int before converting to a receiving type (GCC, Clang). I suppose you could say MS's choice reflects a commitment to backwards compatibility, whereas GCC/Clang is always chomping at the bit to introduce more aggressive optimizations that signed-integer-undefined-behavior affords?
pjmlp
It is much safer to pack/unpack bits manually than trusting bitfields will work as expected.
fsckboy
> The troublesome behavior is demonstrated by the lines performing the left shift. We take a 12-bit wide bit-field, shift it left by 20 bits so ... this is nonsense. I don't know what they expect would happen, but who cares? I wouldn't shift a 12 bit field by more than ±11 bits. you can shift the "enclosing" word of memory if you want, just put the original definition in a union.
wahern
It's even more confusing than described. C23 6.7.3.1p7 says, > Each of the comma-separated multisets designates the same type, except that for bit-fields, it is implementation-defined whether the specifier `int` designates the same type as `signed int` or the same type as `unsigned int`. That means a bit-field member using plain `int` as the underlying type might itself be signed or unsigned, similar to whether plain `char` is signed or unsigned. There's a proposal to address this: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3828.pdf Fortunately, it found that GCC, Clang, MSVC, and ICC all treat `int` bit-fields as `signed int`, and the recommendation is to require this behavior. That said, I don't think I've ever seen a bit-field deliberately used for signed values; there's some logic to the allowance granted by the standard. And I'm sure there's plenty of real-world code erroneously using `int` bit-fields for unsigned values that just happens to work because of twos-complement representations and the semantics of bitwise operations. But better to limit this kind of flexibility, especially when real-world implementations seem not to have taken the alternative route.
kazinator
You're supposed to know that bitfields undergo promotion as they were small integers, even if they are declared to be something like unsigned int. Therefore, convert the values before operating on them: u1 = ((uint64_t) bf.uf1) << 20; u2 = ((uint64_t) bf.uf2) << 20;