Почему в VTT есть top_offset, реализованный gcc?

Вот подробное описание VTT в ответе с наибольшим количеством голосов. Но ответ не объясняет, почему существует top-offset в VTT.

С моей точки зрения, когда мы down_cast base указатель на derived указатель, компилятор уже знает 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    |         +-----------------------+
      +----------+

Почему есть top_offset в VTT при такой ситуации? я думаю top_offset а также virtual base offset нужны только при виртуальном наследовании.

1 ответ

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

Компилятор не может определить во время компиляции, что является правильным смещением. Эта функция может быть вызвана с нулевым указателем, указателем на завершенный B объект или указатель на B субобъект. Три случая должны быть обработаны по-разному. Смещение в vtable - то, что позволяет этому работать.

Другие вопросы по тегам