为什么 VTT 中有 GCC 实施的top_offset?

Why is there a top_offset in VTT implemented by gcc?

本文关键字:top offset VTT 中有 GCC 为什么      更新时间:2023-10-16

这是在投票最多的答案中对VTT的详细说明。但答案并不能解释为什么 VTT 中有top-offset

在我看来,当我们down_cast指向derived指针的base指针时,编译器已经知道编译时(没有虚拟派生时(需要调整offset,因此无需在以下情况下存储top_offset

class A {
public:
int a;
};
class B {
public:
int b;
virtual void w();
};
class C : public A, public B {
public:
int c;
};

在这种情况下,C 类型的对象布局如下(假设为 32 位指针的数字(:

+-----------------------+
|     0 (top_offset)    |//why?
+-----------------------+
c --> +----------+         | ptr to typeinfo for C |
|  vtable  |-------> +-----------------------+
+----------+         |         A::v()        |
|     a    |         +-----------------------+
+----------+         |    -8 (top_offset)    |//why?
|  vtable  |---+     +-----------------------+
+----------+   |     | ptr to typeinfo for C |
|     b    |   +---> +-----------------------+
+----------+         |         B::w()        |
|     c    |         +-----------------------+
+----------+

为什么在这种情况下,VTT会有top_offset我认为top_offsetvirtual base offset仅在虚拟继承中需要。

void *top(B *b) { return dynamic_cast<void *>(b); }

编译器无法在编译时确定正确的偏移量是什么。可以使用 null 指针、指向完整B对象的指针或指向B子对象的指针来调用此函数。这三种情况需要以不同的方式处理。vtable 中的偏移量是允许它工作的原因。