Spec-Zone.ru › GCC 11

Следующая: Предикаты C++ интерфейса и реализации, Предыдущая: Ограничение алиасов указателей, Вверх: Расширения языка C++ [Оглавление][Индекс]

7.3 Неявная связь ¶

Существует несколько конструкций в C++, которые требуют места в объектных файлах, но не имеют явной связи с отдельным модулем трансляции. Говорят, что эти конструкции имеют «неявную связь». Обычно такие конструкции генерируются в любом месте, где они необходимы, хотя иногда мы можем действовать более продуманно.

Встроенные функции

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

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

Таблицы vtable

Виртуальные функции C++ реализуются в большинстве компиляторов с помощью таблицы поиска, известной как vtable. Таблица vtable содержит указатели на виртуальные функции, предоставляемые классом, и каждый объект класса содержит указатель на свою vtable (или vtable, в некоторых ситуациях с множественным наследованием). Если класс объявляет какие-либо не встроенные, не чистые виртуальные функции, первая из них выбирается в качестве «ключевого метода» для класса, и vtable генерируется только в том модуле трансляции, где определяется ключевой метод.

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

type_info объекты

C++ требует, чтобы информация о типах была записана для реализации ‘dynamic_cast’, ‘typeid’ и обработки исключений. Для полиморфных классов (классы с виртуальными функциями) объект ‘type_info’ записывается вместе с vtable, чтобы ‘dynamic_cast’ мог определить динамический тип объекта класса во время выполнения. Для всех других типов мы записываем объект ‘type_info’ при его использовании: при применении ‘typeid’ к выражению, бросании объекта или ссылке на тип в блоке catch или спецификации исключения.

Шаблонные инстанциации

Практически все в этом разделе также относится к шаблонным инстанциациям, но есть и другие варианты. См. Где шаблон?.

При использовании с GNU ld версии 2.8 или выше на системах ELF, таких как GNU/Linux или Solaris 2, или на Microsoft Windows, дублированные копии этих конструкций будут удалены на этапе компоновки. Это известно как поддержка COMDAT.

На целевых платформах, которые не поддерживают COMDAT, но поддерживают слабые символы, GCC использует их. Таким образом, одна копия переопределяет все остальные, но неиспользуемые копии все равно занимают место в исполняемом файле.

Для целей, которые не поддерживают ни COMDAT, ни слабые символы, большинство сущностей с неявной связью генерируются как локальные символы, чтобы избежать ошибок дублирования определения от компоновщика. Однако это не относится к локальным статикам во встроенных функциях, поскольку наличие нескольких копий почти наверняка нарушит работу.

См. Объявления и определения в одном заголовке, чтобы узнать другой способ управления размещением этих конструкций.

Следующая: Предикаты C++ интерфейса и реализации, Предыдущая: Ограничение алиасов указателей, Вверх: Расширения языка C++ [Оглавление][Индекс]

© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-11.4.0/gcc/Vague-Linkage.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API