Language linkage
Provides for linkage between modules written in different programming languages.
extern string-literal { declaration-seq(optional) }
|
(1) | ||||||||
extern string-literal declaration
|
(2) | ||||||||
string-literal | - | The name of the required language linkage |
declaration-seq | - | a sequence of declarations, which may include nested linkage specifications |
declaration | - | a declaration |
Explanation
Every function type, every function name with external linkage, and every variable name with external linkage, has a property called language linkage. Language linkage encapsulates the set of requirements necessary to link with a module written in another programming language: calling convention, name mangling algorithm, etc.
Only two language linkages are guaranteed to be supported:
extern "C" { int open(const char *pathname, int flags); // C function declaration } int main() { int fd = open("test.txt", 0); // calls a C function from a C++ program } // This C++ function can be called from C code extern "C" void handler(int) { std::cout << "Callback invoked\n"; // It can use C++ }
Since language linkage is part of every function type, pointers to functions maintain language linkage as well. Language linkage of function types (which represents calling convention) and language linkage of function names (which represents name mangling) are independent of each other:
extern "C" void f1(void(*pf)()); // declares a function f1 with C linkage, // which returns void and takes a pointer to a C function // which returns void and takes no parameters extern "C" typedef void FUNC(); // declares FUNC as a C function type that returns void // and takes no parameters FUNC f2; // the name f2 has C++ linkage, but its type is C function extern "C" FUNC f3; // the name f3 has C linkage and its type is C function void() void (*pf2)(FUNC*); // the name pf2 has C++ linkage, and its type is // "pointer to a C++ function which returns void and takes one // argument of type 'pointer to the C function which returns void // and takes no parameters'" extern "C" { static void f4(); // the name of the function f4 has internal linkage (no language) // but the function's type has C language linkage }
Two functions with the same name and the same parameter list in the same namespace cannot have two different language linkages (note, however, that linkage of a parameter may permit such overloading, as in the case of std::qsort and std::bsearch). Likewise, two variables in the same namespace cannot have two different language linkages.
Special rules for "C" linkage
Notes
Language specifications can only appear in namespace scope
The braces of the language specification do not establish a scope.
When language specifications nest, the innermost specification is the one that is in effect.
A function can be re-declared without a linkage specification after it was declared with a language specification, the second declaration will reuse the first language linkage. The opposite is not true: if the first declaration has no language linkage, it is assumed "C++", and redeclaring with another language is an error.
A declaration directly contained in a language linkage specification is treated as if it contains the extern specifier for the purpose of determining the linkage of the declared name and whether it is a definition.
extern "C" int x; // a declaration and not a definition // The above line is equivalent to extern "C" { extern int x; } extern "C" { int x; } // a declaration and definition
References
- C++14 standard (ISO/IEC 14882:2014):
- 7.5 Linkage specifications [dcl.link]
- C++11 standard (ISO/IEC 14882:2011):
- 7.5 Linkage specifications [dcl.link]