Spec-Zone.ru › GCC 4

7.4 #pragma interface и реализация

#pragma interface и #pragma implementation предоставляют пользователю способ явно указать компилятору на выпуск сущностей с неясной ссылкой (и информацией отладки) в конкретном файле трансляции.

Примечание: Начиная с GCC 2.7.2, эти #pragma не полезны в большинстве случаев из-за поддержки COMDAT и эвристики «ключевого метода», упомянутой в Неясной ссылке. Их использование может фактически увеличить размер вашей программы из-за ненужных внестрочных копий встроенных функций. В настоящее время (3.4) единственная польза от этих #pragma заключается в сокращении дублирования информации отладки, и эта проблема скоро будет решена на целевых платформах DWARF 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’ без аргумента, это относится к файлу заголовка с тем же базовым именем1, что и ваш исходный файл. Например, в allclass.cc, использование просто ‘#pragma implementation’ эквивалентно ‘#pragma implementation "allclass.h"’.

В версиях GNU C++ до 2.6.0 allclass.h обрабатывался как файл реализации, когда вы включали его из allclass.cc даже если вы никогда не указывали ‘#pragma implementation’. Однако, это было признано проблематичным и отключено.

Используйте строковый аргумент, если вы хотите, чтобы один файл реализации включал код из нескольких файлов заголовков. (Вы также должны использовать ‘#include’, чтобы включить файл заголовка; ‘#pragma implementation’ только указывает, как использовать файл — он его фактически не включает.)

Нет способа разбить содержимое одного файла заголовка на несколько файлов реализации.

‘#pragma implementation’ и ‘#pragma interface’ также влияют на встроенные функции.

Если вы определили класс в файле заголовка, помеченном ‘#pragma interface’, эффект на встроенную функцию, определенную в этом классе, аналогичен явным extern объявлениям — компилятор вообще не генерирует код для определения независимой версии функции. Его определение используется только для встроенного вызова у вызывающих функций.

Обратно, когда вы включаете тот же файл заголовка в основной исходный файл, который объявляет его как ‘#pragma implementation’, компилятор генерирует код для самой функции; это определяет версию функции, которая может быть найдена через указатели (или вызывающими функциями, скомпилированными без встроенного вызова). Если все вызовы функции могут быть встроены, вы можете избежать генерации функции, скомпилировав с -fno-implement-inlines. Если некоторые вызовы не будут встроены, вы получите ошибки компоновщика.

Примечания

[1] Базовым именем файла является имя, очищенное от всей информации о пути и от окончательных суффиксов, таких как ‘.h’, ‘.C’ или ‘.cc’.

© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-4.9.4/gcc/C_002b_002b-Interface.html

Spec-Zone.ru

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