C bitfields guarantees
Richard (Rikki) Andrew Cattermole
richard at cattermole.co.nz
Fri Jul 5 21:25:41 UTC 2024
On 06/07/2024 9:12 AM, Steven Schveighoffer wrote:
> On Friday, 5 July 2024 at 19:56:49 UTC, Tim wrote:
>> On Friday, 5 July 2024 at 19:35:10 UTC, Steven Schveighoffer wrote:
>>>
>>> What if you need > 32 bits or want to pack into a `ulong`? Is the
>>> behavior sane across compilers?
>>
>> The following struct has a different layout for different platforms:
>
> ...
>
> Thanks for this.
>
> 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;
> };
> ```
>
> Here there are only `uint` bitfields, yet the compiler chooses to layout
> the bits differently based on the *preceding* field.
>
> Walter, I have to unfortunately withdraw my support for defining D
> bitfields to just be the same as C bitfields -- the minefields are too
> subtle. The statement that "If you use uint as the field type, you'll
> get the same layout across every C compiler" is not true. And I don't
> think we can really specify the true nature of what you must do for
> portable bitfields in a way that is straightforward. Saying something
> like "you can only use `uint` bitfields in structs that contain only
> `uint` types" is not a good feature.
>
> I'm back to requesting that we have a mechanism to request C bitfields
> (such as marking a struct as `extern(C)`), or picking one C style and
> going with that.
>
> -Steve
I did not expect this.
This prevents my mitigation from working.
So now we also have to put it into an anonymous struct to even get the
layout we think it should be.
```c
struct Foo {
unsigned short x;
struct {
unsigned int a : 12;
unsigned int b : 12;
unsigned int c : 8;
};
//void* next;
};
int main() {
struct Foo foo;
foo.a = 1;
foo.b = 0;
return 0;
}
```
```asm
main:
push rbp
mov rbp,rsp
mov DWORD PTR [rbp-0x4],0x0
mov eax,DWORD PTR [rbp-0x8]
and eax,0xfffff000
or eax,0x1
mov DWORD PTR [rbp-0x8],eax
mov eax,DWORD PTR [rbp-0x8]
and eax,0xff000fff
or eax,0x0
mov DWORD PTR [rbp-0x8],eax
xor eax,eax
pop rbp
ret
```
More information about the Digitalmars-d
mailing list