181 lines
9.8 KiB
Markdown
181 lines
9.8 KiB
Markdown
[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.12 Linkage 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.7 Program and linkage [basic.link]") between C++ and non-C++ code fragments can
|
||
be achieved using a [*linkage-specification*](#nt:linkage-specification "9.12 Linkage specifications [dcl.link]"):
|
||
|
||
[linkage-specification:](#nt:linkage-specification "9.12 Linkage specifications [dcl.link]")
|
||
extern [*unevaluated-string*](lex.string.uneval#nt:unevaluated-string "5.13.6 Unevaluated strings [lex.string.uneval]") { [*declaration-seq*](dcl.pre#nt:declaration-seq "9.1 Preamble [dcl.pre]")opt }
|
||
extern [*unevaluated-string*](lex.string.uneval#nt:unevaluated-string "5.13.6 Unevaluated strings [lex.string.uneval]") [*name-declaration*](dcl.pre#nt:name-declaration "9.1 Preamble [dcl.pre]")
|
||
|
||
The [*unevaluated-string*](lex.string.uneval#nt:unevaluated-string "5.13.6 Unevaluated 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.2 Universal character names [lex.universal.char]")*s* have been replaced ([[lex.string.uneval]](lex.string.uneval "5.13.6 Unevaluated strings"))[.](#2.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
This document specifies the semantics for the[*unevaluated-string*](lex.string.uneval#nt:unevaluated-string "5.13.6 Unevaluated strings [lex.string.uneval]")*s* "C" and "C++"[.](#2.sentence-4)
|
||
|
||
Use of an [*unevaluated-string*](lex.string.uneval#nt:unevaluated-string "5.13.6 Unevaluated 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.12 Linkage 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.3 Import 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.12 Linkage specifications [dcl.link]") shall inhabit a namespace scope[.](#5.sentence-4)
|
||
|
||
In a [*linkage-specification*](#nt:linkage-specification "9.12 Linkage 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.1 Preamble [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.12 Linkage specifications [dcl.link]") is treated as if it contains theextern specifier ([[dcl.stc]](dcl.stc "9.2.2 Storage 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.2 Storage 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)
|