3 ms·
C++ also supports this. However, you still end up needing to do a bunch of operations, the compiler just hides it from you which is why I think Chen opted not t
by slaymaker1907 2y ago
C++ also supports this. However, you still end up needing to do a bunch of operations, the compiler just hides it from you which is why I think Chen opted not to use it.
struct my_bitfield
{
uint16_t b:5;
uint16_t g:6;
uint16_t r:5;
};
bool IsEveryComponentGreaterThanOrEqual4(my_bitfield x, my_bitfield y)
{
return x.b > y.b && x.g > y.b && x.r > y.r;
}
- kevin_thibedeau 2y agoC bitfields aren't packed. You have to resort to compiler extensions to get that behavior.
- angiosperm 2y agoWhich C compiler doesn't pack bitfields? Anything on x86 or ARM is bound by the ABI to pack in a standard and link-compatible way. Seems there would only be a problem on some proprietary compiler for an embedded, bespoke target.
- o11c 2y agoI think SDCC has weird bitfields, originally due to a bug but now baked into the ABI for some of its platforms? But there are only a handful of ways to lay out bitfields: * Use little-endian or big-endian bit order? (this need not match the byte order, but usually does - IIRC recent GCC no longer supports any platforms where it doesn't?). This is the only one you can't control. Networking headers rely on a 2-way preprocessor branch so no other ways are really possible, at least up to `unsigned int` (may be 16) bits. * If padding is needed, is it on the left or on the right? or, on the top or on the bottom? (this might always be tied to bit-endianness, but theoretically it is detached). For maximum portability, you must add explicit padding, doing math with `CHAR_BIT`. * What exactly happens if an over-sized bitfield is attempted? (beware, there is no stable ABI for this in practice!) * Do zero-sized bitfields align to the next unit? * Can bitfields cross units? Is perhaps a larger-than-user-specified unit used? Consider `struct {uint8_t a:4, b:8, c:4};` * If a mixture of types is used, do they get aggregated unconditionally, by size, by type? Ignoring signedness or not? Consider `struct { int a:1; long b:1; long long c:1; }` * Is `int` the same as `signed int` or `unsigned int`, and for what widths? It's unfortunate that testing some of these can't be done at compile time (a few can via `sizeof`), so you may need to either manually inspect assembly code, or else rely on optimization to do the emit-constants-via-strings trick when cross-compiling (C++, if supported on your platform, may do better than C at accessible compile-time optimization).
- vlovich123 2y agoNot sure where you got that from. I think you’re confusing it with structs. > Consecutive bit fields are packed together, but each bit field must fit within a single object of its specified type [1] https://www.gnu.org/software/c-intro-and-ref/manual/html_node/Bit-Field-Packing.html https://www.gnu.org/software/c-intro-and-ref/manual/html_nod...
- samatman 2y agoSome differences: the standard doesn't guarantee that C++ bitfields will be densely packed (this is mostly a technicality), you can't have non-const bitfields, and you can't take a pointer to a bitfield. Zig's pointer-to-bitfield is a special type, for obvious reasons, but they can come in handy. I have no idea if the requirement that each bitfield be reified as its declared type inhibits optimization of that example or not, in practice. Maybe, maybe not.