Спецификации компоновки
Термином "спецификация компоновки" обозначается протокол связывания функций (или процедур), написанных на разных языках. Затрагиваются следующие соглашения о вызовах:
Учет регистра в именах.
Декорирование имен. В языке C компилятор добавляет перед именами символ подчеркивания. Часто это называется "декорированием". В языке C++ декорирование имен используется для сохранения информации на этапе компоновки. (См. раздел Декорированные имена)
Порядок, в котором аргументы размещаются в стеке.
Ответственность за настройку стека при возврате из функции. Ответственность может лежать на вызываемой или вызывающей функции.
Передача скрытых аргументов (передаются ли какие-либо скрытые аргументы).
extern string-literal { declaration-list }
extern string-literal declaration
Спецификация компоновки облегчает постепенный перенос кода на языке C в язык C++, позволяя использовать существующий код.
Блок, относящийся только к системам Microsoft
В настоящее время Microsoft C++ поддерживает только спецификации компоновки "C" и "C++".
Завершение блока, относящегося только к системам Microsoft
В следующем примере объявляются функции atoi и atol с компоновкой C:
extern "C"
{
int atoi( char *string );
long atol( char *string );
}
Вызовы этих функций производятся с использованием компоновки C. Этот же результат можно получить с помощью следующих двух объявлений:
extern "C" int atoi( char *string );
extern "C" long atol( char *string );
Блок, относящийся только к системам Microsoft
Все стандартные включаемые файлы Microsoft C содержат директивы условной компиляции для обнаружения компиляция C++. При обнаружении компиляции C++ прототипы заключаются в директиву extern "C", как показано ниже:
// Sample.h
#if defined(__cplusplus)
extern "C"
{
#endif
// Function declarations
#if defined(__cplusplus)
}
#endif
Завершение блока, относящегося только к системам Microsoft
Нет необходимости объявлять функции в стандартных включаемых файлах как extern "C".
Если функция перегружена, описатель компоновки может иметь не более чем одна функция с таким именем. (Дополнительные сведения см. в разделе Перегрузка функций.)
В следующей таблице показано, как работают различные спецификации компоновки.
Действие спецификаций компоновки
Спецификация |
Действие |
---|---|
Для объекта |
Влияет на компоновку только этого объекта |
Для функции |
Влияет на компоновку этой функции и всех функций или объектов, объявленных в ней |
Для класса |
Влияет на компоновку всех объявленных в классе функций и объектов, не являющихся членами |
Если у функции несколько спецификаций компоновки, они должны быть согласованы; если для функции объявлены компоновки C и C++ — это ошибка. Кроме того, если в программе имеются два объявления функции (одно со спецификацией компоновки, а другое без такой спецификации), объявление с указанием компоновки должен быть первым. Ко всем повторным объявлениям функций, уже имеющих спецификацию компоновки, применяется компоновка из первого объявления. Например:
extern "C" int CFunc1();
...
int CFunc1(); // Redeclaration is benign; C linkage is
// retained.
int CFunc2();
...
extern "C" int CFunc2(); // Error: not the first declaration of
// CFunc2; cannot contain linkage
// specifier.
Функции и объекты, явно объявленные как static в теле составного описателя компоновки ({ }), рассматриваются как статические функции или объекты; описатель компоновки игнорируется. Остальные функции и объекты ведут себя так, как если бы они были объявлены с помощью ключевого слова extern. (Подробнее о ключевом слове extern см. в разделе Использование extern для указания компоновки.)