оптимизация компилятора единого виртуального наследования в c ++? - PullRequest
1 голос
/ 04 февраля 2012

Если у меня есть такая ситуация в проекте C ++:

  • 1 базовый класс 'Base', содержащий только чистые виртуальные функции
  • 1 класс 'Derived', который является единственным классом, которыйнаследует (public) от 'Base'

Будет ли компилятор генерировать VTABLE?

Кажется, в этом нет необходимости, поскольку проект содержит только 1 класс, на который указывает указатель Base *может указывать (Derived), так что это может быть разрешено время компиляции для всех случаев.

Это интересно, если вы хотите сделать внедрение зависимостей для модульного тестирования, но не хотите, чтобы расходы на поиск VTABLE в производствекод.

Ответы [ 3 ]

6 голосов
/ 04 февраля 2012

У меня нет точных данных, но у меня есть веские причины сказать нет, виртуальные вызовы не будут преобразованы в статические.

  • Обычно компилятор видит только один модуль компиляции,Он не может знать, есть только один подкласс, потому что пять месяцев спустя вы можете написать другой подкласс, скомпилировать его, получить некоторые древние объектные файлы из резервной копии и связать их все вместе.
  • Пока ссылкаОптимизации по времени действительно видят всю картину, они обычно работают на гораздо более низкоуровневом представлении программы.Такое представление позволяет, например, встраивать статические вызовы, но не представляет информацию о наследовании (за исключением, возможно, необязательных метаданных), и уже имеет виртуальные вызовы и виртуальные таблицы, прописанные в явном виде.Я знаю , это так, что оптимизация всей программы Clang и IIRC gcc также работает на некотором низкоуровневом IR (GIMPLE?).
  • Также обратите внимание, что при динамической загрузке вы можете все еще добавляет больше подклассов долго после компиляции и LTO.Возможно, вам это не понадобится, но если бы я был автором компилятора, я бы устал добавлять оптимизацию, которая позволяла бы пользователям по-королевски прерывать виртуальные вызовы в очень специфических, трудных для отслеживания обстоятельствах.
  • Эторедко стоит потрудиться - если вам не нужны виртуальные вызовы (например, потому что вы знаете, что вам не нужно больше подклассов), не делайте вещи virtual.Пересмотрите свой дизайн.Если вам нужен некоторый полиморфизм, но не полная виртуальная мощь, любопытно повторяющийся шаблон может помочь.
0 голосов
/ 04 февраля 2012

vtable обычно используется не только для виртуальных функций, но также используется для определения типа класса, когда вы делаете dynamic_cast или когда программа обращается к type_info для класса.

Если компилятор обнаруживает, что никакие виртуальные функции никогда не нуждаются в динамической диспетчеризации, и никакие другие функции не используются, он может просто удалить указатель vtable в качестве оптимизации.

Очевидно, что компилятор не нашел его достойнымБеда в этом.Возможно, потому что это не будет использоваться очень часто.

0 голосов
/ 04 февраля 2012

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

...