7.4 Предикаты интерфейса и реализации C++
#pragma interface и #pragma implementation предоставляют пользователю возможность явно указать компилятору на генерацию сущностей с неясными ссылками (и отладочной информацией) в определенном трансляционном блоке.
Примечание: Эти #pragma устарели начиная с GCC 2.7.2 в пользу поддержки COMDAT и эвристики «ключевого метода», упомянутых в Нечетких ссылках. Их использование может привести к увеличению размера вашей программы из-за ненужных внестрочных копий встроенных функций.
#pragma interface#pragma interface "subdir/objects.h"-
Используйте эту директиву в заголовочных файлах, определяющих классы объектов, для экономии места в большинстве объектных файлов, использующих эти классы. Обычно локальные копии определенной информации (резервные копии встроенных функций-членов, отладочная информация и внутренние таблицы, реализующие виртуальные функции) должны храниться в каждом объектном файле, включающем определения классов. Вы можете использовать этот предикат, чтобы избежать такой дублирования. Когда заголовочный файл, содержащий ‘#pragma interface’, включается в компиляцию, эта вспомогательная информация не генерируется (если только сам основной входной исходный файл не использует ‘#pragma implementation’). Вместо этого объектные файлы содержат ссылки, которые будут разрешены во время компоновки.
Вторая форма этой директивы полезна в случае, когда у вас есть несколько заголовочных файлов с одинаковым именем в разных каталогах. Если вы используете эту форму, вы должны указать ту же строку в ‘#pragma implementation’.
#pragma implementation#pragma implementation "objects.h"-
Используйте этот предикат в главном входном файле, когда вы хотите получить полную информацию из включенных заголовочных файлов (и сделать ее глобально видимой). В свою очередь, включенный заголовочный файл должен использовать ‘#pragma interface’. Резервные копии встроенных функций-членов, отладочная информация и внутренние таблицы, используемые для реализации виртуальных функций, генерируются во всех файлах реализации.
Если вы используете ‘#pragma implementation’ без аргументов, это применяется к включаемому файлу с тем же базовым именем4, что и ваш исходный файл. Например, в allclass.cc, использование только ‘#pragma implementation’ эквивалентно ‘#pragma implementation "allclass.h"’.
Используйте строковый аргумент, если вы хотите, чтобы один файл реализации включал код из нескольких заголовочных файлов. (Вы также должны использовать ‘#include’, чтобы включить заголовочный файл; ‘#pragma implementation’ только указывает, как использовать файл — он его не включает).
Нет способа разбить содержимое одного заголовочного файла на несколько файлов реализации.
‘#pragma implementation’ и ‘#pragma interface’ также влияют на встроенность функций.
Если вы определите класс в заголовочном файле, помеченном ‘#pragma interface’, влияние на встроенную функцию, определенную в этом классе, аналогично явным extern объявлениям — компилятор вообще ничего не генерирует для определения независимой версии функции. Ее определение используется только для встраивания с вызывающими ее функциями.
Наоборот, когда вы включаете тот же заголовочный файл в основной исходный файл, объявляя его как ‘#pragma implementation’, компилятор генерирует код для самой функции; это определяет версию функции, которая может быть найдена через указатели (или вызывающими функциями, скомпилированными без встраивания). Если все вызовы функции могут быть встроены, вы можете избежать генерации функции, скомпилировав с -fno-implement-inlines. Если какие-либо вызовы не могут быть встроены, у вас будут ошибки компоновщика.
Примечания
Базовое имя файла — это имя, очищенное от всей информации о пути и от суффиксов, таких как ‘.h’ или ‘.C’ или ‘.cc’.
Далее: Шаблонная инстанциация, Предыдущее: Нечеткие ссылки, Вверх: Расширения C++ [Оглавление][Индекс]
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-8.5.0/gcc/C_002b_002b-Interface.html