Files
cppdraft_translate/cppdraft/dcl/ref.md
2025-10-25 03:02:53 +03:00

169 lines
8.4 KiB
Markdown
Raw 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.ref]
# 9 Declarations [[dcl]](./#dcl)
## 9.3 Declarators [[dcl.decl]](dcl.decl#dcl.ref)
### 9.3.4 Meaning of declarators [[dcl.meaning]](dcl.meaning#dcl.ref)
#### 9.3.4.3 References [dcl.ref]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3137)
In a declarationTD whereD has either of the forms
& [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt D1
&& [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt D1
and the type of the contained [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]") in the declarationTD1 is “*derived-declarator-type-list*T”,
the type of the [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]") inD is “*derived-declarator-type-list* reference toT”[.](#1.sentence-1)
The optional [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") appertains to the reference type[.](#1.sentence-2)
Cv-qualified references are ill-formed except when the cv-qualifiers
are introduced through the use of a[*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4The typedef specifier[dcl.typedef]") ([[dcl.typedef]](dcl.typedef "9.2.4The typedef specifier"), [[temp.param]](temp.param "13.2Template parameters")) or[*decltype-specifier*](dcl.type.decltype#nt:decltype-specifier "9.2.9.6Decltype specifiers[dcl.type.decltype]") ([[dcl.type.decltype]](dcl.type.decltype "9.2.9.6Decltype specifiers")),
in which case the cv-qualifiers are ignored[.](#1.sentence-3)
[*Example [1](#example-1)*: typedef int& A;const A aref = 3; // error: lvalue reference to non-const initialized with rvalue
The type ofaref is “lvalue reference to int”,
not “lvalue reference to const int”[.](#1.sentence-4)
— *end example*]
[*Note [1](#note-1)*:
A reference can be thought of as a name of an object[.](#1.sentence-5)
— *end note*]
Forming the type
“reference to cv void”
is ill-formed[.](#1.sentence-6)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3183)
A reference type that is declared using & is called an[*lvalue reference*](#def:lvalue_reference "9.3.4.3References[dcl.ref]"), and a reference type that
is declared using && is called an[*rvalue reference*](#def:rvalue_reference "9.3.4.3References[dcl.ref]")[.](#2.sentence-1)
Lvalue references and
rvalue references are distinct types[.](#2.sentence-2)
Except where explicitly noted, they are
semantically equivalent and commonly referred to as references[.](#2.sentence-3)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3191)
[*Example [2](#example-2)*:
void f(double& a) { a += 3.14; }// ...double d = 0;
f(d); declaresa to be a reference parameter off so the callf(d) will add3.14 tod[.](#3.sentence-1)
int v[20];// ...int& g(int i) { return v[i]; }// ... g(3) = 7; declares the functiong() to return a reference to an integer sog(3)=7 will assign7 to the fourth element of the arrayv[.](#3.sentence-2)
For another example,struct link { link* next;};
link* first;
void h(link*& p) { // p is a reference to pointer p->next = first;
first = p;
p = 0;}void k() { link* q = new link;
h(q);} declaresp to be a reference to a pointer tolink soh(q) will leaveq with the value zero[.](#3.sentence-3)
See also [[dcl.init.ref]](dcl.init.ref "9.5.4References")[.](#3.sentence-4)
— *end example*]
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3258)
It is unspecified whether or not
a reference requires storage ([[basic.stc]](basic.stc "6.8.6Storage duration"))[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3262)
There shall be no references to references,
no arrays of references, and no pointers to references[.](#5.sentence-1)
The declaration of a reference shall contain an[*initializer*](dcl.init.general#nt:initializer "9.5.1General[dcl.init.general]") ([[dcl.init.ref]](dcl.init.ref "9.5.4References"))
except when the declaration contains an explicitextern specifier ([[dcl.stc]](dcl.stc "9.2.2Storage class specifiers")),
is a class member ([[class.mem]](class.mem "11.4Class members")) declaration within a class definition,
or is the declaration of a parameter or a return type ([[dcl.fct]](dcl.fct "9.3.4.6Functions")); see [[basic.def]](basic.def "6.2Declarations and definitions")[.](#5.sentence-2)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3275)
Attempting to bind a reference to a function where
the converted initializer is a glvalue whose
type is not call-compatible ([[expr.call]](expr.call "7.6.1.3Function call"))
with the type of the function's definition
results in undefined behavior[.](#6.sentence-1)
Attempting to bind a reference to an object where
the converted initializer is a glvalue through which
the object is not type-accessible ([[basic.lval]](basic.lval "7.2.1Value category"))
results in undefined behavior[.](#6.sentence-2)
[*Note [2](#note-2)*:
The object designated by such a glvalue can be
outside its lifetime ([[basic.life]](basic.life "6.8.4Lifetime"))[.](#6.sentence-3)
Because a null pointer value or a pointer past the end of an object
does not point to an object,
a reference in a well-defined program cannot refer to such things;
see [[expr.unary.op]](expr.unary.op "7.6.2.2Unary operators")[.](#6.sentence-4)
As described in [[class.bit]](class.bit "11.4.10Bit-fields"), a reference cannot be bound directly
to a bit-field[.](#6.sentence-5)
— *end note*]
The behavior of an evaluation of a reference ([[expr.prim.id]](expr.prim.id "7.5.5Names"), [[expr.ref]](expr.ref "7.6.1.5Class member access")) that
does not happen after ([[intro.races]](intro.races "6.10.2.2Data races")) the initialization of the reference
is undefined[.](#6.sentence-6)
[*Example [3](#example-3)*: int &f(int&);int &g();extern int &ir3;int *ip = 0;int &ir1 = *ip; // undefined behavior: null pointerint &ir2 = f(ir3); // undefined behavior: ir3 not yet initializedint &ir3 = g();int &ir4 = f(ir4); // undefined behavior: ir4 used in its own initializerchar x alignas(int);int &ir5 = *reinterpret_cast<int *>(&x); // undefined behavior: initializer refers to char object — *end example*]
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3315)
If a [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4The typedef specifier[dcl.typedef]") ([[dcl.typedef]](dcl.typedef "9.2.4The typedef specifier"), [[temp.param]](temp.param "13.2Template parameters"))
or a [*decltype-specifier*](dcl.type.decltype#nt:decltype-specifier "9.2.9.6Decltype specifiers[dcl.type.decltype]") ([[dcl.type.decltype]](dcl.type.decltype "9.2.9.6Decltype specifiers")) denotes a type TR that
is a reference to a type T, an attempt to create the type “lvalue reference to cv TR”
creates the type “lvalue reference to T”, while an attempt to create
the type “rvalue reference to cv TR” creates the type TR[.](#7.sentence-1)
[*Note [3](#note-3)*:
This rule is known as reference collapsing[.](#7.sentence-2)
— *end note*]
[*Example [4](#example-4)*: int i;typedef int& LRI;typedef int&& RRI;
LRI& r1 = i; // r1 has the type int&const LRI& r2 = i; // r2 has the type int&const LRI&& r3 = i; // r3 has the type int& RRI& r4 = i; // r4 has the type int& RRI&& r5 = 5; // r5 has the type int&&decltype(r2)& r6 = i; // r6 has the type int&decltype(r2)&& r7 = i; // r7 has the type int& — *end example*]
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3343)
[*Note [4](#note-4)*:
Forming a reference to function type is ill-formed if the function
type has [*cv-qualifier*](dcl.decl.general#nt:cv-qualifier "9.3.1General[dcl.decl.general]")*s* or a [*ref-qualifier*](dcl.decl.general#nt:ref-qualifier "9.3.1General[dcl.decl.general]");
see [[dcl.fct]](dcl.fct "9.3.4.6Functions")[.](#8.sentence-1)
— *end note*]