C bitfields guarantees

Timon Gehr timon.gehr at gmx.ch
Wed Jul 10 00:32:53 UTC 2024


On 7/9/24 01:52, Walter Bright wrote:
> On 7/7/2024 3:42 AM, Timon Gehr wrote:
>> If it is simple, you should have no trouble stating how it works 
>> completely in a couple sentences.
> 
> One sentence:
> 
> If the bitfields of type T start on a T alignment boundary and do not 
> straddle a T alignment boundary, then the bitfields will be portable.
> ...

Well, this is not a complete characterization, but good enough I guess.

So the preferred alignment of a bitfield of a given width is not 
portable? I.e., are there so-called sane C compilers where a `uint:16` 
has an (actual) alignment of 4 instead of 2?

> I agree I sometimes have trouble writing exact specifications, but I'm 
> also confident that you understand this.
> ...

Sure, but I really think we should just enforce this kind of rule for 
`extern(D)` bitfields. If a programmer does not follow the rule, just 
error out and present options to the programmer for how to make the code 
compile:

error: bitfield layout is ambiguous

- add extern(C) to match the layout of the associated C compiler
- add padding and/or 0-width bitfields to unambiguously start bitfields 
on a T alignment boundary without straddling

A priori you just don't know which of those was intended. It's good to 
require explicit input here, as it is subtle.

> 
>> I am as a result now not sure whether what you stated is the full 
>> truth, or it is still some inadmissible simplification that glosses 
>> over some further dragons.
> 
> Feel free to try pathological examples and let me know of any adverse 
> discoveries.
> 
> 
>> Also, I hope `.offsetof % .alignof != 0` is just a bug in your 
>> bitfield implementation.
> 
> ??
> 

It's elaborated upon in the part of the post you ignored:

On 7/7/24 12:42, Timon Gehr wrote:
> 
> Also consider this:
> 
> ```d
> struct S{
>      uint x;
>      ulong y:30;
>      ulong z:34;
> }
> pragma(msg, S.y.offsetof, " ", S.y.alignof); // 4LU 8LU
> 
> The offset of `y` does not even respect its alignment! This is insanity.
> 
> It also happens with `uint`:
> 
> ```d
> struct S{
>      ushort x;
>      uint y:16;
> }
> pragma(msg, S.y.offsetof, " ", S.y.alignof); // 2LU 4LU 



More information about the Digitalmars-d mailing list