[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<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.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*]
