C bitfields guarantees

Walter Bright newshound2 at digitalmars.com
Sat Jul 6 00:16:23 UTC 2024


On 7/5/2024 2:12 PM, Steven Schveighoffer wrote:
> I also tested the following, and found it too shows discrepancies.
> 
> ```c
> struct S {
>      unsigned short x;
>      unsigned int a : 12;
>      unsigned int b : 12;
>      unsigned int c : 8;
> };
> ```

The following will also show discrepancies:

```
struct T {
     unsigned short x;
     unsigned int y;
}
```

for the same reason.

 > Here there are only uint bitfields, yet the compiler chooses to layout the 
bits differently based on the preceding field.

It's actually based on the *alignment* of the preceding field. I'm regret not 
saying that, but that's what I meant with the fields need to be of the same 
type, so they have the same alignment. If the uint bitfield started off aligned 
at a uint boundary, my statement holds.

When mixing field types of different sizes, there will be different alignments 
of those fields on different platforms/compilers, whether or not bitfields are 
involved.

The layout can be portably controlled as desired, by being cognizant of field 
alignment:

```c
struct S {
      unsigned short x;
      unsigned short a : 12;  // at offset 2
      unsigned int   b : 12;  // at offset 4
      unsigned int   c : 8;   // at offset 4
};
```

```c
struct S {
      unsigned short x;
      unsigned short dummy;   // for alignment porpoises
      unsigned int a : 12;    // at offset 4
      unsigned int b : 12;    // at offset 4
      unsigned int c : 8;     // at offset 4
};
```

Simply put, avoiding fields that straddle alignment boundaries avoids 
portability issues. This is true with both bitfields and regular fields.


More information about the Digitalmars-d mailing list