C bitfields guarantees
Timon Gehr
timon.gehr at gmx.ch
Fri Jul 5 09:13:26 UTC 2024
On 7/5/24 07:37, Richard (Rikki) Andrew Cattermole wrote:
> Today many people have spent some time to try and understand Walter's
> belief that C is "good enough" for bit fields in terms of guarantees.
>
> I believe I have understood a core component to this.
>
> From the C23 standard:
>
>> An implementation may allocate any addressable storage unit large
>> enough to hold a bit-field. If
> enough space remains, a bit-field that immediately follows another
> bit-field in a structure shall be
> packed into adjacent bits of the same unit. If insufficient space
> remains, whether a bit-field that
> does not fit is put into the next unit or overlaps adjacent units is
> implementation-defined. The
> order of allocation of bit-fields within a unit (high-order to low-order
> or low-order to high-order) is
> implementation-defined. The alignment of the addressable storage unit is
> unspecified.
>
> What matters is the _initial_ type in the bit-field, the rest of the
> types _do not_ matter.
> ...
According to this text, none of the types matter for layout guarantees.
Only the bit sizes matter somewhat. And then the implementation still
has way too much leeway in how it allocates things.
Walter's reasoning has been that _in practice_, C implementations are a
bit more sane than what the standard allows. I don't think it is
fruitful to try and find any useful guarantees in the standard. If there
were any, that's what Walter would point to instead.
> As long as you _do not_ start and finish in two separate memory
> addresses for that initial type it will be predictable.
> ...
According to the standard, no.
E.g.:
int a:7;
int b:25;
According to the standard, this could put `a` in a 1-byte unit and `b`
in a subsequent 32-byte unit. It could put `a` in a 1-byte unit, use the
last bit for `b`, then put the remaining 24 bits of `b` in a new unit.
It could also put both in separate 4-byte integers. Or it could pack
them into a single 4-byte location. It is not specified. In practice,
implementations will usually put both of them in a single 4-byte
location, and this is what Walter is relying on. The C standard gives
you almost nothing (it could even choose to put both `a` and `b` into a
8-byte or larger unit, there is no upper limit on the size, only a lower
one.)
And I did not even get into different possible orderings of bit fields
within a unit.
More information about the Digitalmars-d
mailing list