Первый адрес vtable в GCC? - PullRequest
       43

Первый адрес vtable в GCC?

4 голосов
/ 25 апреля 2019

Когда я строю, разбираю и очищаю эту короткую программу:

struct Base {
    virtual int compute() { return 42; }
};

struct Derived: public Base {
    int compute() override { return 23; }
};

int main() {
    Base* a = new Derived;
    a->compute();
}

Что я делаю с некоторой домашней магией:

g++ -g -o- -S foo.cpp | \
    c++filt | \
    perl -pe 's/^\.LA\w+:\r?\n//gm' | \
    perl -0777 -pe 's/^\.Ldebug\w+:\r?\n(\s+\..+?\r?\n)+//gm' | \
    perl -pe 's/^\.L\w+:\r?\n//gm' | \
    perl -pe 's/^\s+\.(align|section|weak|loc|file|cfi).+\r?\n//gm' | \
    highlight --out-format=ansi --syntax=asm

Я получаю это:

vtable for Derived:
        .quad   0
        .quad   typeinfo for Derived
        .quad   Derived::compute()
        .type   vtable for Base, @object
        .size   vtable for Base, 24
vtable for Base:
        .quad   0
        .quad   typeinfo for Base
        .quad   Base::compute()
        .type   typeinfo for Derived, @object
        .size   typeinfo for Derived, 24

Я заметил, что мой vtable имеет следующую структуру:

0. ???
1. Pointer to typeinfo
2. Pointer to first virtual method
3. Pointer to second virtual method
4. ...

Я не понял, что было 0 в vtable[0], но после обнаружения этого другого ТАК вопрос, я написал другой пример, чтобы понять это смещение наверх вещь.

https://godbolt.org/z/eWScPK

Этот использует виртуальное наследование.

struct Top {
    virtual void foo() { }
};

struct Left: public Top { // note: non virtual
    void foo() override { }
};

struct Right: virtual public Top {
    void foo() override { }
};
// note: Bottom is not a "diamond", Top is base twice
struct Bottom: public Left, public Right {
    void foo() override { }
};

int main() {
    Bottom bottom;
    bottom.foo();
}

На этот раз мой vtable выглядит так:

vtable for Bottom:
        .word   4
        .word   0
        .word   typeinfo for Bottom
        .word   Bottom::foo()
        .word   0
        .word   -4
        .word   -4
        .word   typeinfo for Bottom
        .word   non-virtual thunk to Bottom::foo()

ИтакЯ могу объяснить первый 0, который стал 4, но я все еще не в состоянии объяснить новую структуру моего vtable.

Я ищу более подробный ответ, который объяснил бы этот последний пример.

...