[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.1 Attribute syntax and semantics [dcl.attr.grammar]")opt D1 && [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt D1 and the type of the contained [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [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.1 General [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.1 Attribute 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.4 The typedef specifier [dcl.typedef]") ([[dcl.typedef]](dcl.typedef "9.2.4 The typedef specifier"), [[temp.param]](temp.param "13.2 Template parameters")) or[*decltype-specifier*](dcl.type.decltype#nt:decltype-specifier "9.2.9.6 Decltype specifiers [dcl.type.decltype]") ([[dcl.type.decltype]](dcl.type.decltype "9.2.9.6 Decltype 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.3 References [dcl.ref]"), and a reference type that is declared using && is called an[*rvalue reference*](#def:rvalue_reference "9.3.4.3 References [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.4 References")[.](#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.6 Storage 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.1 General [dcl.init.general]") ([[dcl.init.ref]](dcl.init.ref "9.5.4 References")) except when the declaration contains an explicitextern specifier ([[dcl.stc]](dcl.stc "9.2.2 Storage class specifiers")), is a class member ([[class.mem]](class.mem "11.4 Class members")) declaration within a class definition, or is the declaration of a parameter or a return type ([[dcl.fct]](dcl.fct "9.3.4.6 Functions")); see [[basic.def]](basic.def "6.2 Declarations 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.3 Function 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.1 Value 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.4 Lifetime"))[.](#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.2 Unary operators")[.](#6.sentence-4) As described in [[class.bit]](class.bit "11.4.10 Bit-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.5 Names"), [[expr.ref]](expr.ref "7.6.1.5 Class member access")) that does not happen after ([[intro.races]](intro.races "6.10.2.2 Data 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(&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.4 The typedef specifier [dcl.typedef]") ([[dcl.typedef]](dcl.typedef "9.2.4 The typedef specifier"), [[temp.param]](temp.param "13.2 Template parameters")) or a [*decltype-specifier*](dcl.type.decltype#nt:decltype-specifier "9.2.9.6 Decltype specifiers [dcl.type.decltype]") ([[dcl.type.decltype]](dcl.type.decltype "9.2.9.6 Decltype 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.1 General [dcl.decl.general]")*s* or a [*ref-qualifier*](dcl.decl.general#nt:ref-qualifier "9.3.1 General [dcl.decl.general]"); see [[dcl.fct]](dcl.fct "9.3.4.6 Functions")[.](#8.sentence-1) — *end note*]