DECLSPEC_NOVTABLE на чистых виртуальных классах? - PullRequest
1 голос
/ 12 марта 2009

Это, вероятно, обычная избыточность программирования. Я заметил DECLSPEC_NOVTABLE (__declspec (novtable)) на связке интерфейсов, определенных в заголовках:

struct DECLSPEC_NOVTABLE IStuff : public IObject
{
    virtual method1 () = 0;
    virtual method2 () = 0;
};

В статье MSDN об этом расширенном атрибуте __declspec говорится, что добавление этого парня удалит записи vtable конструкции и дескриптора и, следовательно, приведет к "значительному уменьшению размера кода" (поскольку vtable будет полностью удален).

Это просто не имеет особого смысла для меня. Эти ребята чисто виртуальные, почему бы компилятору не сделать это по умолчанию?

В статье также говорится, что если вы сделаете это, а затем попытаетесь создать одну из этих вещей, вы получите нарушение прав доступа во время выполнения. Но когда я попробовал это с несколькими компиляторами (с расширением __declspec или без него), они не компилируются (как я и ожидал).

Итак, я думаю, чтобы подвести итог:

  • Компилятор удаляет vtable независимо от чисто виртуальных интерфейсов, или я пропустил что-то фундаментальное здесь?
  • О чем говорится в статье MSDN?

Ответы [ 2 ]

2 голосов
/ 12 марта 2009

Компилятор удаляет единственную ссылку на vtable, которая была бы во время создания класса. Поэтому компоновщик может оптимизировать его, поскольку в коде больше нет ссылки на него.

Кстати, у меня есть привычка объявлять пустой конструктор как protected, а также использовать ключевое слово расширения abstract от Microsoft, чтобы избежать такого нарушения доступа во время выполнения. Таким образом, компилятор улавливает проблему во время компиляции (поскольку только базовый класс может создать экземпляр интерфейса через защищенный конструктор). Производный класс, конечно, будет заполнять vtable во время его строительства.

1 голос
/ 12 марта 2009

Это немного ручная работа для тупого компилятора / компоновщика. Компилятор не должен вставлять ссылки на этот vtable, так как совершенно очевидно, что он не нужен. Компилятор также может пометить ссылку таким образом, чтобы компоновщик мог исключить vtable, но это, конечно, сложнее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...