Why does bindgen add alignment fields to repr(C) unions?

When bindgen generates unions, it always(?) adds the _bindgen_union_align field. However, it also generates the #[repr(C)] annotation, which seems to guarantee the same size and alignment as a compatible C union.

If repr(C) should be enough, why is the alignment field added? Can it be removed from the generated bindings?

1 Like

Can you show an example?

#[repr(C)]
#[derive(Copy, Clone)]
pub union some_union {
    pub field1: another_type_1,
    pub field2: another_type_2,
    // ...

    _bindgen_union_align: [u64; 33usize], // <- this
}

What types are the other fields?

Basically, because sometimes it might be required, and because it doesn't hurt anything to have there. It's a bit of explicit redundancy.

All kinds, really. Some unions have only basic data types (integers, chars, arrays), others have struct and union fields. All of the unions have the _bindgen_union_align, anyways.

I see, but I'm wondering what are the circumstances where it might be required.

I'm asking, because I do not want to invoke bindgen through a build script on every platform where my project is built (for a bunch of reasons). I want to have the bindings generated once, and used everywhere. Managing these _bindgen_union_align fields adds to the maintenance burden. I'm trying to understand the implications of dropping them altogether.

1 Like

Well if it's any help I looked back to when it was first added and I see this issue which lead to this PR.

1 Like

Excellent, thanks!

Also, issue 1560 sheds more light on this question.

So, if I understand it correctly, the idea behind adding the _bindgen_union_align field is to enforce proper alignment of the generated Rust unions in cases where the underlying C unions have explicit alignment attributes: __attribute__((aligned(16))). This made perfect sense before Rust 1.25, which introduced the #[repr(align(x))] attribute. Nowadays it seems to only be required for backward compatibility.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.