-
Notifications
You must be signed in to change notification settings - Fork 748
Bitfields should be packed into earlier fields if alignment allows so. #1377
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This looks actually pretty hard to fix, looks like the compiler packs the typedef unsigned char uint8_t;
typedef unsigned uint32_t;
struct Foo {
uint8_t available_spare : 1;
uint8_t temperature : 1;
uint8_t device_reliability : 1;
uint8_t read_only : 1;
uint8_t volatile_memory_backup : 1;
uint8_t reserved : 3;
};
struct Bar {
struct Foo foo;
uint32_t ns_attr_notice : 1;
uint32_t fw_activation_notice : 1;
uint32_t telemetry_log_notice : 1;
uint32_t reserved : 21;
}; I'm not sure what code should we actually generate to make this work. Sigh, bitfields. |
A bit more reduced, without the extra struct: typedef unsigned char uint8_t;
typedef unsigned uint32_t;
struct Bar {
uint8_t foo;
uint32_t ns_attr_notice: 1;
uint32_t fw_activation_notice: 1;
uint32_t telemetry_log_notice: 1;
uint32_t reserved: 21;
}; |
union
size is different between Rust and C
I'm trying to solve this problem,
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Bar {
pub foo: u8,
pub _bitfield_align_1: [u32; 0],
pub _bitfield_1: __BindgenBitfieldUnit<[u8; 3usize]>,
} But in reality, the existing code structure is difficult to solve this problem. We have to parse everything in a large function, just like pressing bullets into the magazine one by one struct C {
unsigned char x; /* 0 1 */
/* Bitfield combined with previous fields */
unsigned int b1:1; /* 0: 8 4 */
/* XXX 7 bits hole, try to pack */
/* Bitfield combined with next fields */
unsigned char y; /* 2 1 */
/* Bitfield combined with previous fields */
unsigned int b2:1; /* 0:24 4 */
/* size: 4, cachelines: 1, members: 4 */
/* sum members: 2 */
/* sum bitfield members: 2 bits, bit holes: 1, sum bit holes: 7 bits */
/* bit_padding: 7 bits */
/* last cacheline: 4 bytes */
}; When parsing pub struct C {
pub x: ::std::os::raw::c_uchar,
pub _bitfield_align_1: [u8; 0],
pub _bitfield_1: __BindgenBitfieldUnit<[u8; 3usize]>,
pub y: ::std::os::raw::c_uchar,
pub _bitfield_align_2: [u8; 0],
pub _bitfield_2: __BindgenBitfieldUnit<[u8; 1usize]>,
} |
Per the discussion with @emilio on issue #687, I create this new issue for better tracking.
Input C/C++ Header
I have the following structure definition in C
It is translated as
However, during
cargo test
, the following test is failedThe corresponding test is
and the failure happens at
From what I see, the
union
is 4 bytes on C but becomes 8 bytes in its corresponding Rust translation.The
spdk_nvme_critical_warning_state
insidespdk_nvme_feat_async_event_configuration
reported above is defined asBindgen Invocation
Actual Results
See above.
Expected Results
union
structure expected to be 4 bytes large but got 8 bytes instead.The text was updated successfully, but these errors were encountered: