You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
thread 'bindgen_test::bindgen_test_layout_OtherThing' panicked at 'assertion failed: `(left == right)`
left: `16`,
right: `12`: Offset of field: OtherThing::b', ...project/target/debug/build/my-project-238c3bd8fa97c21f/out/bindings.rs:49:5
Full generated code:
/* automatically generated by rust-bindgen */#[repr(C)]pubstructThing__bindgen_vtable(::std::os::raw::c_void);#[repr(C)]#[derive(Debug,Copy,Clone)]pubstructThing{pubvtable_:*constThing__bindgen_vtable,puba:::std::os::raw::c_int,}#[test]fnbindgen_test_layout_Thing(){assert_eq!(::std::mem::size_of::<Thing>(),16usize,
concat!("Size of: ", stringify!(Thing)));assert_eq!(::std::mem::align_of::<Thing>(),8usize,
concat!("Alignment of ", stringify!(Thing)));assert_eq!(unsafe{&(*(::std::ptr::null::<Thing>())).a as*const _ asusize},8usize,
concat!("Offset of field: ", stringify!(Thing),"::", stringify!(a)));}#[repr(C)]#[derive(Debug,Copy,Clone)]pubstructOtherThing{pub_base:Thing,pubb:::std::os::raw::c_int,}#[test]fnbindgen_test_layout_OtherThing(){assert_eq!(::std::mem::size_of::<OtherThing>(),16usize,
concat!("Size of: ", stringify!(OtherThing)));assert_eq!(::std::mem::align_of::<OtherThing>(),8usize,
concat!("Alignment of ", stringify!(OtherThing)));assert_eq!(unsafe{&(*(::std::ptr::null::<OtherThing>())).b as*const _ asusize},12usize,
concat!("Offset of field: ",
stringify!(OtherThing),"::",
stringify!(b)));}
Expected Results
It is reported that Thing has a size of 16, which makes sense since the vtable is 8 bytes (on my system), the int a is 4 bytes but the whole struct has an alignment of 8, so 4 bytes of padding are added.
which includes the 4 bytes of padding inside Thing.
I assume that clang "inlines" the members (and vtable) of the base-class and reuses the padding, while in the Rust code the padding is preserved.
So in C++ the layout for OtherThing would look like this
0.. 7 vtable
8..11 a
12..15 b
while rust keeps the padding
0.. 7 vtable
8..11 a
12..15 padding
16..19 b
19..23 padding
This is resolved properly when removing the virtual method and adding a void * as the first member of Thing, so maybe somewhere the vtable is not considered properly?
The text was updated successfully, but these errors were encountered:
A base-class with virtual methods might mess up the alignment of a sub-class' members (as well as size).
(the tests fail before the alignment check, but if it's commented out those fail as well)
Apparently this only happens when the base-class has members itself (and are smaller than
sizeof(void *)
it seems. Padding problems?)Input C/C++ Header
Bindgen Invocation
Actual Results
Full generated code:
Expected Results
It is reported that
Thing
has a size of 16, which makes sense since the vtable is 8 bytes (on my system), theint a
is 4 bytes but the whole struct has an alignment of 8, so 4 bytes of padding are added.The generated code for
OtherThing
iswhich includes the 4 bytes of padding inside
Thing
.I assume that clang "inlines" the members (and vtable) of the base-class and reuses the padding, while in the Rust code the padding is preserved.
So in C++ the layout for
OtherThing
would look like thiswhile rust keeps the padding
This is resolved properly when removing the virtual method and adding a
void *
as the first member ofThing
, so maybe somewhere the vtable is not considered properly?The text was updated successfully, but these errors were encountered: