10 Declarations [dcl.dcl]

10.5 Linkage specifications [dcl.link]

Все типы функций, имена функций с внешней связью и имена переменных с внешней связью имеют расширение 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 noteNote: string-literal Ada ADA Fortran FORTRANend 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 noteExample:

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

Связь из C ++ с объектами, определенными на других языках, и с объектами, определенными в C ++ из других языков, определяется реализацией и зависит от языка. Такая связь может быть достигнута только в том случае, если стратегии размещения объектов двух языковых реализаций достаточно схожи.