0

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.

xxllxx666
  • 183
  • 1
  • 6
  • A few (unrelated) things: First of all please [don't post images of text](https://meta.stackoverflow.com/questions/285551/why-should-i-not-upload-images-of-code-data-errors-when-asking-a-question); Secondly, why are you using `printf` for output in your C++ program? Also, `long` isn't guaranteed to be 64 bits, and can therefore not be used to hold addresses. Just like all other type the actual size depends on multiple factors. – Some programmer dude Jul 15 '22 at 06:11
  • Please post text, not images. – KamilCuk Jul 15 '22 at 06:20
  • @Someprogrammerdude, what's wrong with `printf`? – Elliott Jul 15 '22 at 06:43
  • @Elliott Type-safety, as I mentioned. Take for the example the OP using the `%lx` format specifier to print a `long` value. The problem is that the `x` format implies an *unsigned* value, while `long` is a *signed* value. Mismatching format specifier and argument value type leads to *undefined behavior*. With `std::cout` and the overloaded `<<` operator there's no such problems. – Some programmer dude Jul 15 '22 at 07:28

1 Answers1

1
  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

Nimrod
  • 2,908
  • 9
  • 20