Files
2025-10-25 03:02:53 +03:00

181 lines
9.8 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[dcl.link]
# 9 Declarations [[dcl]](./#dcl)
## 9.12 Linkage specifications [dcl.link]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9126)
All functions and variables whose names have external linkage
and all function types
have a [*language linkage*](#def:language_linkage "9.12Linkage specifications[dcl.link]")[.](#1.sentence-1)
[*Note [1](#note-1)*:
Some of the properties associated with an entity with language linkage
are specific to each implementation and are not described here[.](#1.sentence-2)
For
example, a particular language linkage might be associated with a
particular form of representing names of objects and functions with
external linkage, or with a particular calling convention, etc[.](#1.sentence-3)
— *end note*]
The default language linkage of all function types, functions, and
variables is C++ language linkage[.](#1.sentence-4)
Two function types with
different language linkages are distinct types even if they are
otherwise identical[.](#1.sentence-5)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9142)
[Linkage](basic.link "6.7Program and linkage[basic.link]") between C++ and non-C++ code fragments can
be achieved using a [*linkage-specification*](#nt:linkage-specification "9.12Linkage specifications[dcl.link]"):
[linkage-specification:](#nt:linkage-specification "9.12Linkage specifications[dcl.link]")
extern [*unevaluated-string*](lex.string.uneval#nt:unevaluated-string "5.13.6Unevaluated strings[lex.string.uneval]") { [*declaration-seq*](dcl.pre#nt:declaration-seq "9.1Preamble[dcl.pre]")opt }
extern [*unevaluated-string*](lex.string.uneval#nt:unevaluated-string "5.13.6Unevaluated strings[lex.string.uneval]") [*name-declaration*](dcl.pre#nt:name-declaration "9.1Preamble[dcl.pre]")
The [*unevaluated-string*](lex.string.uneval#nt:unevaluated-string "5.13.6Unevaluated strings[lex.string.uneval]") indicates the required language linkage[.](#2.sentence-2)
[*Note [2](#note-2)*:
Escape sequences and [*universal-character-name*](lex.universal.char#nt:universal-character-name "5.3.2Universal character names[lex.universal.char]")*s* have been replaced ([[lex.string.uneval]](lex.string.uneval "5.13.6Unevaluated strings"))[.](#2.sentence-3)
— *end note*]
This document specifies the semantics for the[*unevaluated-string*](lex.string.uneval#nt:unevaluated-string "5.13.6Unevaluated strings[lex.string.uneval]")*s* "C" and "C++"[.](#2.sentence-4)
Use of an [*unevaluated-string*](lex.string.uneval#nt:unevaluated-string "5.13.6Unevaluated strings[lex.string.uneval]") other than "C" or "C++" is conditionally-supported,
with implementation-defined semantics[.](#2.sentence-5)
[*Note [3](#note-3)*:
Therefore, a [*linkage-specification*](#nt:linkage-specification "9.12Linkage specifications[dcl.link]") with a language linkage
that is unknown to the implementation requires a diagnostic[.](#2.sentence-6)
— *end note*]
*Recommended practice*: The spelling of the language linkage should be taken
from the document defining that language[.](#2.sentence-7)
For example, Ada (not ADA) andFortran or FORTRAN, depending on the vintage[.](#2.sentence-8)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9175)
Every implementation shall provide for linkage to the C programming language,"C", and C++, "C++"[.](#3.sentence-1)
[*Example [1](#example-1)*: complex sqrt(complex); // C++ language linkage by defaultextern "C" {double sqrt(double); // C language linkage} — *end example*]
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9189)
A [*module-import-declaration*](module.import#nt:module-import-declaration "10.3Import declaration[module.import]") appearing in
a linkage specification with other than C++ language linkage
is conditionally-supported withimplementation-defined semantics[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9196)
Linkage specifications nest[.](#5.sentence-1)
When linkage specifications nest, the
innermost one determines the language linkage[.](#5.sentence-2)
[*Note [4](#note-4)*:
A linkage specification does not establish a scope[.](#5.sentence-3)
— *end note*]
A [*linkage-specification*](#nt:linkage-specification "9.12Linkage specifications[dcl.link]") shall inhabit a namespace scope[.](#5.sentence-4)
In a [*linkage-specification*](#nt:linkage-specification "9.12Linkage specifications[dcl.link]"),
the specified language linkage applies
to the function types of all function declarators and
to all functions and variables whose names have external linkage[.](#5.sentence-5)
[*Example [2](#example-2)*: extern "C" // f1 and its function type have C language linkage;void f1(void(*pf)(int)); // pf is a pointer to a C functionextern "C" typedef void FUNC();
FUNC f2; // f2 has C++ language linkage and// its type has C language linkageextern "C" FUNC f3; // f3 and its type have C language linkagevoid (*pf2)(FUNC*); // the variable pf2 has C++ language linkage; its type// 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,// so f4 has no language linkage; its 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*]
A C language linkage is ignored
in determining the language linkage of
class members,
friend functions with a trailing [*requires-clause*](temp.pre#nt:requires-clause "13.1Preamble[temp.pre]"), and the
function type of non-static class member functions[.](#5.sentence-6)
[*Example [3](#example-3)*: extern "C" typedef void FUNC_c();
class C {void mf1(FUNC_c*); // the function mf1 and its type have C++ language linkage;// the parameter has type “pointer to C function'' FUNC_c mf2; // the function mf2 and its type have C++ language linkagestatic FUNC_c* q; // the data member q has C++ language linkage;// its type is “pointer to C function''};
extern "C" {class X {void mf(); // the function mf and its type have C++ language linkagevoid mf2(void(*)()); // the function mf2 has C++ language linkage;// the parameter has type “pointer to C function''};} — *end example*]
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9271)
If two declarations of an entity give it different language linkages, the
program is ill-formed; no diagnostic is required if neither declaration
is reachable from the other[.](#6.sentence-1)
A redeclaration of an entity without a linkage specification
inherits the language linkage of the entity and (if applicable) its type[.](#6.sentence-2)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9279)
Two declarations declare the same entity
if they (re)introduce the same name,
one declares a function or variable with C language linkage,
and the other declares such an entity or declares a variable
that belongs to the global scope[.](#7.sentence-1)
[*Example [4](#example-4)*: int x;namespace A {extern "C" int f(); extern "C" int g() { return 1; }extern "C" int h(); extern "C" int x(); // error: same name as global-space object x}namespace B {extern "C" int f(); // A::f and B::f refer to the same functionextern "C" int g() { return 1; } // error: the function g with C language linkage has two definitions}int A::f() { return 98; } // definition for the function f with C language linkageextern "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*]
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9307)
A declaration directly contained in a[*linkage-specification*](#nt:linkage-specification "9.12Linkage specifications[dcl.link]") is treated as if it contains theextern specifier ([[dcl.stc]](dcl.stc "9.2.2Storage class specifiers")) for the purpose of determining the linkage of the
declared name and whether it is a definition[.](#8.sentence-1)
Such a declaration shall
not have a [*storage-class-specifier*](dcl.stc#nt:storage-class-specifier "9.2.2Storage class specifiers[dcl.stc]")[.](#8.sentence-2)
[*Example [5](#example-5)*: extern "C" double f();static double f(); // errorextern "C" int i; // declarationextern "C" {int i; // definition}extern "C" static void g(); // error — *end example*]
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9327)
[*Note [5](#note-5)*:
Because the language linkage is part of a function type, when
indirecting through a pointer to C function, the function to
which the resulting lvalue refers is considered a C function[.](#9.sentence-1)
— *end note*]
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9334)
Linkage from C++ to entities defined in other languages and to entities
defined in C++ from other languages is implementation-defined and
language-dependent[.](#10.sentence-1)
Only where the object layout strategies of two
language implementations are similar enough can such linkage be
achieved[.](#10.sentence-2)