Why do I have to specify a type for a bit field?
struct MyBitField
{
unsigned int i : 4;
}
struct MyBitField2
{
unsigned char i : 4;
}
What's the difference between those two? Why do I need to specify a type at all?
Bitfields are an "overlay" around normal members, and every member has a type. Recall that integer types in C++ are largely inherited from types in C, which were designed to map neatly to whatever primitives exist on the target architecture. This is a convenient feature to have. Bitfields sit on top of that logic; they do not replace it.
A few facts regarding this:
The "special width" of a bitfield does not contribute to its type;
the number of usable bytes of a bitfield depend on its type (bits beyond the natural width of the type are considered padding);
the semantics of an assignment to a bitfield depend (to some degree) on its type.
Types fundamentally underpin how objects work in C++, and how the values of those objects are to be encoded and interpreted.
Could the bitfield feature have been designed differently? As, perhaps, a separate first-class kind of thing in the language that did not require a specific underlying type?
Perhaps, but then you'd need new rules to define bitfield integer semantics (both signed and unsigned) and conversion rules for every combination of assignment. What would be the point? We already have a type system we can use.
In your case, sure, the semantics of each object shown is the same. But other bitfields exist. You may as well ask why both unsigned int
and unsigned long
exist, on a system for which their respective ranges are identical: we don't design the language around very specific cases.
If all you want is a collection of untyped bits, then std::bitset<4>
is what you're looking for.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With