Search code examples
c++multiple-inheritancememory-layoutvirtual-destructorvirtual-table

C++ Memory Layout: Questions about multiple inheritance, virtual destructors, and virtual function tables


I have a main.cpp file as follows.

#include <stdio.h>

class Base1
{
public:
    int ibase1;
    Base1() : ibase1(10) {}
    virtual void f_b1_1() { printf("Base1::f_b1_1()()\n"); }
    virtual void f_b1_2() { printf("Base1::f_b1_2()()\n"); }
    virtual ~Base1() { printf("Base1::~Base1()\n"); }
};
class Base2
{
public:
    int ibase2;
    Base2() : ibase2(20) {}
    virtual void f_b2_1() { printf("Base2::f_b2_1()()\n"); }
    virtual void f_b2_2() { printf("Base2::f_b1_2()()\n"); }
    virtual ~Base2() { printf("Base2::~Base2()\n"); }
};
class Base3
{
public:
    int ibase3;
    Base3() : ibase3(30) {}
    virtual void f_b3_1() { printf("Base3::f_b3_1()\n"); }
    virtual void f_b3_2() { printf("Base3::f_b3_2()\n"); }
    virtual ~Base3() { printf("Base3::~Base3()\n"); }
};
class Derive : public Base1, public Base2, public Base3
{
public:
    int iderive;
    Derive() : iderive(100) {}
    virtual void f_b1_1() { printf("Derive::f_b1_1()\n"); }
    virtual void f_b2_1() { printf("Derive::f_b2_1()\n"); }
    virtual void f_b3_1() { printf("Derive::f_b2_1()\n"); }
    virtual void f_d_1() { printf("Derive::f_d_1()\n"); }
    virtual ~Derive() { printf("Derive::~Derive()\n"); }
};

int main()
{
    Derive d;
    long **pVtab = (long **)&d;
    for (int i = -2; i <= 18; ++i)
    {
        printf("vtab offset=%d  addr=%lx\n", (i + 2) * 8, pVtab[0][i]);
    }
    return 0;
}

I use the g++ -fdump-lang-class -c main.cpp command to view the memory layout of the object, which generates the main.cpp.001l.class file, the following is part of that file. enter image description here

And the output of main.cpp is as follows.

enter image description here

My questions are:

  1. What is the meaning of the content in the red box?
  2. What is the relationship between Derive::_ZThn16_N6Derive6f_b2_1Ev and Derive::f_b2_1?
  3. What is the relationship between Derive::_ZThn16_N6Derive6f_b3_1Ev and Derive::f_b3_1?
  4. Are Derive::_ZThn16_N6DeriveD1Ev, Derive::_ZThn16_N6DeriveD0Ev, Derive::_ZThn32_N6DeriveD1Ev, Derive::_ZThn32_N6DeriveD0Ev and Derive::~Derive related?
  5. Does the above relate to "C++ trunk"?

The os is: Ubuntu 20.04

The g++ version is: 9.4.0

What materials should I read?

I look forward to your help and I would like to thank you in advance.


Solution

    1. What is the meaning of the content in the red box?
    2. Does the above relate to "C++ trunk"?

    The symbols you highlighed are mangled, you can use some demangle tools, like c++filt

    > c++filt _ZThn16_N6Derive6f_b2_1Ev
    non-virtual thunk to Derive::f_b2_1()
    

    As to your rest questions, you could refer to What is a 'thunk'? this SO question and answers.

    It's a part of ABI, you could refer to Itanium C++ ABI