This commit is contained in:
2025-10-25 03:02:53 +03:00
commit 043225d523
3416 changed files with 681196 additions and 0 deletions

180
cppdraft/dcl/link.md Normal file
View File

@@ -0,0 +1,180 @@
[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)