Open
Description
Consider the test case in virtual_inheritance.hpp
, C++ will generate memory layout as
&d = 0x7fff566a88b0
offset_of(A::foo)=32
offset_of(B::foo=32
offset_of(C::foo=32
offset_of(B::bar)=24
offset_of(C::baz)=8
offset_of(D::bazz)=28
a = 0x7fff566a88d0
offset_of(A::foo)=0
b = 0x7fff566a88c0
offset_of(A::foo)=16
offset_of(C::baz)=8
c = 0x7fff566a88b0
offset_of(A::foo)=32
offset_of(C::baz)=8
#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
class A {
public:
int foo;
};
class B: public virtual A {
public:
int bar;
};
class C: public virtual A {
public:
int baz;
};
class D: public C, public B {
public:
int bazz;
};
int main() {
D d;
int main() {
D d;
printf("&d = %p\n", &d);
printf("offset_of(A::foo)=%lu\n", (uintptr_t)&d.foo - (uintptr_t)&d);
printf("offset_of(B::foo=%lu\n", (uintptr_t)&((B *)&d)->foo - (uintptr_t)&d);
printf("offset_of(C::foo=%lu\n", (uintptr_t)&((C *)&d)->foo - (uintptr_t)&d);
printf("offset_of(B::bar)=%lu\n", (uintptr_t)&d.bar - (uintptr_t)&d);
printf("offset_of(C::baz)=%lu\n", (uintptr_t)&d.baz - (uintptr_t)&d);
printf("offset_of(D::bazz)=%lu\n", (uintptr_t)&d.bazz - (uintptr_t)&d);
A *a = &d;
printf("a = %p\n", a);
printf("offset_of(A::foo)=%lu\n", (uintptr_t)&a->foo - (uintptr_t)a);
B *b = &d;
printf("b = %p\n", b);
printf("offset_of(A::foo)=%lu\n", (uintptr_t)&b->foo - (uintptr_t)b);
printf("offset_of(C::baz)=%lu\n", (uintptr_t)&b->bar - (uintptr_t)b);
C *c = &d;
printf("c = %p\n", c);
printf("offset_of(A::foo)=%lu\n", (uintptr_t)&c->foo - (uintptr_t)c);
printf("offset_of(C::baz)=%lu\n", (uintptr_t)&c->baz - (uintptr_t)c);
}
bindgen
will generate memory layout as
#[repr(C)]
#[derive(Debug, Copy)]
pub struct B {
pub vtable_: *const B__bindgen_vtable,
pub bar: ::std::os::raw::c_int,
}
#[repr(C)]
#[derive(Debug, Copy)]
pub struct C {
pub vtable_: *const C__bindgen_vtable,
pub baz: ::std::os::raw::c_int,
}
#[repr(C)]
#[derive(Debug, Copy)]
pub struct D {
pub _base: C,
pub _base_1: B,
pub bazz: ::std::os::raw::c_int,
}
First, both C
and B
will be aligned to 16 bytes, it cause D::bazz
be aligned to 32 bytes rather than 28 bytes.
Second, A::foo
should be generated and following D::bazz
.
#[repr(C)]
#[derive(Debug, Copy)]
pub struct D {
pub vtable_c: *const C__bindgen_vtable,
pub baz: ::std::os::raw::c_int,
pub vtable_b: *const B__bindgen_vtable,
pub bar: ::std::os::raw::c_int,
pub bazz: ::std::os::raw::c_int,
pub foo: ::std::os::raw::c_int,
}