Skip to content

Wrong size of class with virtual methods #3095

Closed
@kdanecki

Description

@kdanecki

input C++ header

class Base 
{
public:
      virtual void fun();
      int a;
};

class Derived : public Base
{
public:
      void fun() override;
      int x;
};

bindgen command

bindgen -o foo.rs foo.h -- -x c++

actual result

#[repr(C)]
pub struct Base__bindgen_vtable(::std::os::raw::c_void);
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Base {
    pub vtable_: *const Base__bindgen_vtable,
    pub a: ::std::os::raw::c_int,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of Base"][::std::mem::size_of::<Base>() - 16usize];
    ["Alignment of Base"][::std::mem::align_of::<Base>() - 8usize];
    ["Offset of field: Base::a"][::std::mem::offset_of!(Base, a) - 8usize];
};
unsafe extern "C" {
    #[link_name = "\u{1}_ZN4Base3funEv"]
    pub fn Base_fun(this: *mut ::std::os::raw::c_void);
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Derived {
    pub _base: Base,
    pub x: ::std::os::raw::c_int,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of Derived"][::std::mem::size_of::<Derived>() - 16usize];
    ["Alignment of Derived"][::std::mem::align_of::<Derived>() - 8usize];
    ["Offset of field: Derived::x"][::std::mem::offset_of!(Derived, x) - 12usize];
};
unsafe extern "C" {
    #[link_name = "\u{1}_ZN7Derived3funEv"]
    pub fn Derived_fun(this: *mut ::std::os::raw::c_void);
}

compiler error

error[E0080]: evaluation of constant value failed
  --> foo.rs:29:5
   |
29 |     ["Size of Derived"][::std::mem::size_of::<Derived>() - 16usize];
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the length is 1 but the index is 8

description

When a class with virtual methods is derived, the fields of derived class can occupy padding of the Base class. But rust representation makes sizeof Derived == sizeof Base + sizeof all fields of derived.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions