Linkage, или связывание – это свойство идентификатора, позволяющее компилятору в некоторых случаях создавать для нескольких одинаковых имен, объявленных в разных единицах трансляции, одну общую сущность. Вместе с областью видимости связывание определяет, из каких единиц трансляции и их блоков можно обратиться к сущности.
Существуют 4 вида связывания: no linkage, internal linkage, external linkage и module linkage.
Следующие сущности, объявленные в блочной области видимости, имеют no linkage (иначе говоря, не имеют связывания):
Для каждого имени без связывания компилятор сгенерирует отдельный объект.
Если идентификатор имеет internal linkage (внутреннее связывание), то к нему можно обратиться из любого места текущей единицы трансляции. Для нескольких объявлений одинаковых имен с внутренним связыванием в одной единице трансляции компилятор сгенерирует один объект. Для одинаковых имен с internal linkage в разных единицах трансляции компилятор создаст разные объекты.
Следующие сущности, объявленные в пространстве имен, имеют внутреннее связывание:
Идентификатор, имеющий external linkage (внешнее связывание), доступен из других единиц трансляции. Для одинаковых имен с внешним связыванием компилятор создаст один объект.
Идентификатор, имеющий external linkage, также имеет language linkage, благодаря которому связываются юниты трансляции, написанные на разных языках программирования.
Следующие сущности, объявленные в пространстве имен, имеют external linkage:
Следующие сущности, объявленные в блочной области видимости, имеют external linkage:
Начиная со стандарта C++20, идентификатор может иметь module linkage (модульное связывание). Такой идентификатор доступен из единиц трансляции, входящих в тот же модуль, в котором он объявлен. Соответственно, для нескольких одинаковых объявлений одноименных сущностей с module linkage в рамках одного модуля будет создан один объект.
Module linkage имеют идентификаторы, прикрепленные к именованному модулю и не объявленные с ключевым словом export. Рассмотрим следующий код:
// cute_module_main.h
module CuteModule:moduleVariable;
int moduleVariable = 0;
// cute_module_calculator.h
export module CuteModule;
import :moduleVariable;
export int GetSquaredModuleVariable() {
return ::moduleVariable * ::moduleVariable;
}
Здесь переменная moduleVariable имеет module linkage.
0