rust-bindgen icon indicating copy to clipboard operation
rust-bindgen copied to clipboard

Bitfield in C struct creates zero length arrray _bitfield_align_1

Open hannesweisbach opened this issue 9 months ago • 0 comments

Hi,

I'm working on upgrading rust-bindgen used in the crate nrf-softdevice from 0.55.1 but I've hit a bit of a snag and i'm not sure what to do. I've recreated my issue using the C example code:

#define ARR_LEN 16

struct test
{
    unsigned char id[ARR_LEN];
    unsigned char bit1 : 1;
    unsigned char bit2 : 1;
    unsigned char bits : 6;
};

rust-bindgen 0.55.1 generates this code from this snipped:

pub const ARR_LEN: u32 = 16;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct test {
    pub id: [::std::os::raw::c_uchar; 16usize],
    pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize], u8>,
}

whereas with bindgen 0.71.1 I get the following code:

pub const ARR_LEN: u32 = 16;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct test {
    pub id: [::std::os::raw::c_uchar; 16usize],
    pub _bitfield_align_1: [u8; 0],
    pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>,
}

with the new _bitfiield_align_1 member.

_bitfield_align_1 needs to be initialized and thus breaks the API between old and new generated bindings. If the zero-length array is actually correct and intended I guess it is what it is, but I figure I ask before breaking user code.

Is _bitfield_align_1 as zero-length array intended to be there? And just out of curiosity: How is it enforcing alignment? I'd figure an array u8 has a 1-byte alignment requirement anyway which is trivially fulfilled. But that is just my guess/intuition.

PS: the reason I need to update at all is to get the fix for #2312

hannesweisbach avatar Mar 08 '25 20:03 hannesweisbach