Spec-Zone.ru › GCC 7

7.3 Нечёткие связи

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

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

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

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

VTable

Виртуальные функции C++ в большинстве компиляторов реализуются с помощью таблицы поиска, известной как vtable. Vtable содержит указатели на виртуальные функции, предоставляемые классом, и каждый объект класса содержит указатель на свою vtable (или vtables в ситуациях с множественным наследованием). Если класс объявляет какие-либо не встроенные, не чистые виртуальные функции, то первая из них выбирается в качестве «ключевого метода» для класса, и 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-7.5.0/gcc/Vague-Linkage.html

Spec-Zone.ru

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