|
|
С помощью спецификации-связи можно связать ($$R.3.3) фрагменты программ на С++ и на другом языке:
спецификация-связи:
extern строка-литерал { список-описаний opt }
extern строка-литерал описание
список-описаний:
описание
список-описаний описание
Требуемое связывание задается с помощью строки-литерала. Ее назначение определяется реализацией. Но во всех реализациях должно быть предусмотрено связывание с функцией на языке С ("С") и с функцией на языке С++ ("С++"). По умолчанию связывание задается как "С++", например,
complex sqrt(complex); // по умолчанию связывание с C++
extern "C" {
double sqrt(double); // связывание с C
}
Спецификации связи могут быть вложенными. Спецификация связи
не задает область видимости. Спецификация-связи может встретиться
только в файловой области видимости ($$R.3.2). Спецификация-связи
для класса относится к объектам, описанным в нем, и функциям, не
являющимся членами. Спецификация-связи, относящаяся к некоторой
функции, относится и ко всем объектам и функциям, описанным в ней.
Описание связи, содержащее неизвестную для реализации строку,
считается ошибочным.
Если функция имеет более одной спецификации-связи, то они должны
быть согласованы, т.е. задавать одну и ту же строку-литерал.
Описание функции без указания спецификации-связи не должно
предшествовать первому указанию спецификации связи для этой функции.
Функция может быть описана без указания спецификации связи даже
после явного указания спецификации связи, но связывание, явно заданное
в более раннем описании, не будет устранено таким описанием функции.
Из множества перегруженных функций ($$R.13) с данным именем
не более одной может иметь связывание с языком С, см. $$R.7.4.
Связывание можно установить для объектов, например:
extern "C" { // ... _iobuf_iob[_NFILE]; // ... int _flsbuf(unsigned,_iobuf*); // ... }
Когда задается спецификация связи, то функции и объекты можно описать как статические внутри { }. Для таких функций или объектов команда связывания игнорируется. Иначе, функция, описанная при задании связи, трактуется, как если бы она была явно описана как extern, например, ниже второе описание ошибочно ($$R.7.1.1):
extern "C" double f(); static double f(); // ошибка
Объект, описанный внутри конструкции
extern "C" { /* ... */ }
все же считается определенным, а не просто описанным.
Связывание объектов на С++ с объектами, определенными на других
языках, так же как и обратное связывание, зависит от языков и
реализации. Такое связывание возможно только в том случае, когда
алгоритмы размещения объектов в памяти являются достаточно схожими
для двух языков.
Если для задания связи в строке-литерале из спецификации-связи
используется имя языка программирования, то рекомендуется, чтобы
написание этого имени копировалось из документа, определяющего данный
язык, например, Ada (а не ADA) и Fortran (а не FORTRAN).
| |