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