Provides for linkage between program units written in different programming languages.
This can also be used to detach a declaration from its module. See
.
(since C++20)externstring-literal{declaration-seq(optional)}(1) externstring-literaldeclaration(2) 1) Applies the language specification string-literal to all function types, function names with external linkage and variables with external linkage declared in declaration-seq.
2) Applies the language specification string-literal to a single declaration or definition.
string-literal- an
that names 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
, and every variable name with
, has a property called language linkage. Language linkage encapsulates the set of requirements necessary to link with a program unit written in another programming language:
,
(name decoration) algorithm, etc.
Only two language linkages are guaranteed to be supported:
"C++", the default language linkage.
"C", which makes it possible to link with functions written in the C programming language, and to define, in a C++ program, functions that can be called from the units written in C.
extern"C"{intopen(constchar*path_name,intflags);// C function declaration}intmain(){intfd=open("test.txt",0);// calls a C function from a C++ program}// This C++ function can be called from C codeextern"C"voidhandler(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"voidf1(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 parametersextern"C"typedefvoidFUNC();// declares FUNC as a C function type that returns void// and takes no parametersFUNCf2;// the name f2 has C++ linkage, but its type is C functionextern"C"FUNCf3;// 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"{staticvoidf4();// the name of the function f4 has internal linkage (no language)// but the function's type has C language linkage}If
give it different language linkages, the program is ill-formed; no diagnostic is required if neither declaration is reachable from the other. A redeclaration of an entity without a linkage specification inherits the language linkage of the entity and its type (if exists).
extern"C"intf();extern"C++"intf();// Error: different language linkagesextern"C"intg();intg();// OK, has C language linkageinth();// has C++ language linkage by defaultextern"C"inth();// Error: different language linkagesSpecial rules for "C" linkage
When class members, friend functions with a trailing
,(since C++20) or non-static member functions appear in a "C" language block, the linkage of their types remains "C++" (but parameter types, if any, remain "C"):
extern"C"{classX{voidmf();// the function mf and its type have C++ language linkagevoidmf2(void(*)());// the function mf2 has C++ language linkage;// the parameter has type “pointer to C function”};}template<typenameT>structA{structB;};extern"C"{template<typenameT>structA<T>::B{friendvoidf(B*)requirestrue{}// C language linkage ignored};}namespaceQ{extern"C"voidf();// not ill-formed}Let C be a declaration that declares a function or variable with "C" language linkage. If another declaration D declares an entity with the same name, and it satisfies any of the following conditions, C and D declare the same entity:
D declares a variable that belongs to the global scope.
If C declares a variable, D also declares a variable.
If C declares a function, D also declares a function.
Unlike
, C and D can have different
:
extern"C"{intx;intf();intg(){return1;}}namespaceA{intx;// Error: redefines “x”intf();// OK, redeclares “f”intg(){return1;}// Error: redefines “g”}However, the
of such declarations still apply, which means they should either both declare functions or both declare variables, and the declared entities must have the same type:
namespaceA{extern"C"intx();extern"C"inty();}intx;// Error: redeclares “x” as a different kind of entitynamespaceB{voidy();// Error: redeclares “y” with a different type}Notes
Language specifications can only appear in
.
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 declaration directly contained in a language linkage specification is treated as if it contains the
for the purpose of determining the
of the declared name and whether it is a
.
extern"C"intx;// a declaration and not a definition// The above line is equivalent to extern "C" { extern int x; }extern"C"{intx;}// a declaration and definitionextern"C"doublef();staticdoublef();// error: linkage conflictextern"C"staticvoidg();// error: linkage conflictextern"C" makes it possible to include header files containing declarations of C library functions in a C++ program, but if the same header file is shared with a C program, extern"C" (which is not allowed in C) must be hidden with an appropriate
, typically
:
#ifdef __cplusplusextern"C"intfoo(int,int);// C++ compiler sees this#elseintfoo(int,int);// C compiler sees this#endifThe only modern compiler that differentiates function types with "C" and "C++" language linkages is Oracle Studio, others do not permit overloads that are only different in language linkage, including the overload sets required by the C++ standard (
,
,
,
, and
):
,
,
.
extern"C"usingc_predfun=int(constvoid*,constvoid*);extern"C++"usingcpp_predfun=int(constvoid*,constvoid*);// ill-formed, but accepted by most compilersstatic_assert(std::is_same<c_predfun,cpp_predfun>::value,"C and C++ language linkages shall not differentiate function types.");// following declarations do not declare overloads in most compilers// because c_predfun and cpp_predfun are considered to be the same typevoidqsort(void*base,std::size_tnmemb,std::size_tsize,c_predfun*compar);voidqsort(void*base,std::size_tnmemb,std::size_tsize,cpp_predfun*compar);Keywords
Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR Applied to Behavior as published Correct behavior
C++98 names with internal linkage can have language linkages limited to names with external linkage
C++98 a function with "C" language linkage can
have the same name as a global variable the program is ill-formed in this case
(no diagnostic required if they
appear in different translation units)
C++98 the program was ill-formed if two declarations
only differ in language linkage specifications
(i.e. different string literals following 'extern') the actual language linkages given by
the declarations are compared instead
C++20 friend functions with a trailing requires clause
and "C" language linkage had conflict behaviors "C" language linkage
is ignored in this case
C++98 the linkage of the types of static member functions
appear in "C" language blocks was "C++"the linkage is "C"References
C++23 standard (ISO/IEC 14882:2024):
9.11 Linkage specifications [dcl.link]
C++20 standard (ISO/IEC 14882:2020):
9.11 Linkage specifications [dcl.link]
C++17 standard (ISO/IEC 14882:2017):
10.5 Linkage specifications [dcl.link]
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]
C++03 standard (ISO/IEC 14882:2003):
7.5 Linkage specifications [dcl.link]
C++98 standard (ISO/IEC 14882:1998):
7.5 Linkage specifications [dcl.link]