Все типы функций, имена функций с внешней связью и имена переменных с внешней связью имеют расширение language linkage. [ Note: Некоторые свойства, связанные с сущностью с языковой связью, специфичны для каждой реализации и здесь не описываются. Например, конкретная языковая связь может быть связана с определенной формой представления имен объектов и функций с внешней связью или с определенным соглашением о вызовах и т. Д. ] Языковая связь по умолчанию для всех типов функций, имен функций и имен переменных - это языковая связь C ++. Два типа функций с разными языковыми связями являются разными типами, даже если в остальном они идентичны. — end note
Linkage между фрагментами кода C ++ и не-C ++ можно достичь с помощью linkage-specification:
linkage-specification: extern string-literal { declaration-seqopt } extern string-literal declaration
Значок string-literalуказывает на требуемую языковую связь. Этот международный стандарт определяет семантику для string-literals "C" и "C++". Использование string-literalотличного от "C" или "C++" условно поддерживается с семантикой, определяемой реализацией. [ Note: Следовательно, спецификация связи с string-literalнеизвестным реализации требует диагностики. ] [ Рекомендуется, чтобы написание слова было взято из документа, определяющего этот язык. Например, (не ) и или , в зависимости от урожая. ] — end note Note: string-literal Ada ADA Fortran FORTRAN — end note
Каждая реализация должна обеспечивать связь с функциями , написанных на языке программирования С, "C"и связь с функциями C ++, "C++". [ Example:
complex sqrt(complex); // C++ linkage by default extern "C" { double sqrt(double); // C linkage }
— end example ]
Гнездо характеристик сцепления. Когда спецификации связывания вложены, самая внутренняя из них определяет языковую связь. Спецификация связи не устанавливает объем. А linkage-specificationвстречается только в namespace scope. В a linkage-specificationуказанная языковая связь применяется к типам функций всех деклараторов функций, именам функций с внешней связью и именам переменных с внешней связью, объявленным в linkage-specification. [ Example:
extern "C" // the name f1 and its function type have C language linkage; void f1(void(*pf)(int)); // pf is a pointer to a C function extern "C" typedef void FUNC(); FUNC f2; // the name f2 has C++ language linkage and the // function's type has C language linkage extern "C" FUNC f3; // the name of function f3 and the function's type have C language linkage void (*pf2)(FUNC*); // the name of the variable pf2 has C++ linkage and the type // of pf2 is “pointer to C++ function that takes one parameter of type // pointer to C function” extern "C" { static void f4(); // the name of the function f4 has internal linkage (not C language linkage) // and the function's type has C language linkage. } extern "C" void f5() { extern void f4(); // OK: Name linkage (internal) and function type linkage (C language linkage) // obtained from previous declaration. } extern void f4(); // OK: Name linkage (internal) and function type linkage (C language linkage) // obtained from previous declaration. void f6() { extern void f4(); // OK: Name linkage (internal) and function type linkage (C language linkage) // obtained from previous declaration. }
— end example ] Языковая связь AC игнорируется при определении языковой связи имен членов класса и типа функции функций-членов класса. [ Example:
extern "C" typedef void FUNC_c(); class C { void mf1(FUNC_c*); // the name of the function mf1 and the member function's type have // C++ language linkage; the parameter has type “pointer to C function” FUNC_c mf2; // the name of the function mf2 and the member function's type have // C++ language linkage static FUNC_c* q; // the name of the data member q has C++ language linkage and // the data member's type is “pointer to C function” }; extern "C" { class X { void mf(); // the name of the function mf and the member function's type have // C++ language linkage void mf2(void(*)()); // the name of the function mf2 has C++ language linkage; // the parameter has type “pointer to C function” }; }
— end example ]
Если два объявления объявляют функции с одним и тем же именем и parameter-type-list должны быть членами одного и того же пространства имен или объявляют объекты с одинаковым именем членами одного и того же пространства имен, а объявления дают имена различным языковым связям, программа имеет неправильный формат; Если объявления представлены в разных единицах перевода, диагностика не требуется. За исключением функций со связью C ++, объявление функции без спецификации связи не должно предшествовать первой спецификации связи для этой функции. Функция может быть объявлена без спецификации связывания после того, как была обнаружена явная спецификация связывания; на связь, явно указанную в предыдущем объявлении, такое объявление функции не влияет.
Не более одной функции с определенным именем можно связать с языком C. Два объявления функции со связью на языке C с одним и тем же именем функции (без учета имен пространств имен, которые ее квалифицируют), которые появляются в разных областях пространства имен, относятся к одной и той же функции. Два объявления переменной со связью на языке C с одним и тем же именем (игнорируя имена пространств имен, которые ее квалифицируют), которые появляются в разных областях пространства имен, относятся к одной и той же переменной. Сущность со связью на языке C не должна объявляться с тем же именем, что и переменная в глобальной области видимости, если оба объявления не обозначают одну и ту же сущность; Если объявления представлены в разных единицах перевода, диагностика не требуется. Переменная с привязкой к языку C не должна объявляться с тем же именем, что и функция с привязкой к языку C (игнорируя имена пространств имен, которые определяют соответствующие имена); Если объявления представлены в разных единицах перевода, диагностика не требуется. [ Note: В программе может появиться только одно определение для объекта с данным именем с привязкой к языку C (см. [basic.def.odr]); это означает, что такая сущность не должна определяться более чем в одной области пространства имен. ] [ — end note Example:
int x; namespace A { extern "C" int f(); extern "C" int g() { return 1; } extern "C" int h(); extern "C" int x(); // ill-formed: same name as global-space object x } namespace B { extern "C" int f(); // A::f and B::f refer to the same function extern "C" int g() { return 1; } // ill-formed, the function g with C language linkage has two definitions } int A::f() { return 98; } // definition for the function f with C language linkage extern "C" int h() { return 97; } // definition for the function h with C language linkage // A::h and ::h refer to the same function
— end example ]
Объявление, непосредственно содержащееся в a linkage-specification , рассматривается как содержащееся с extern specifier целью определения связи объявленного имени и того, является ли оно определением. Такое объявление не должно указывать класс хранения. [ Example:
extern "C" double f(); static double f(); // error extern "C" int i; // declaration extern "C" { int i; // definition } extern "C" static void g(); // error
— end example ]
[ Note: Поскольку языковая связь является частью типа функции, при косвенном указании на функцию C функция, на которую ссылается результирующее lvalue, считается функцией C. ] — end note