299 lines
14 KiB
Markdown
299 lines
14 KiB
Markdown
[basic.lval]
|
||
|
||
# 7 Expressions [[expr]](./#expr)
|
||
|
||
## 7.2 Properties of expressions [[expr.prop]](expr.prop#basic.lval)
|
||
|
||
### 7.2.1 Value category [basic.lval]
|
||
|
||
[1](#1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L140)
|
||
|
||
Expressions are categorized according to the taxonomy in Figure [2](#fig:basic.lval)[.](#1.sentence-1)
|
||
|
||

|
||
Figure [2](#fig:basic.lval) — Expression category taxonomy [[fig:basic.lval]](./fig:basic.lval)
|
||
|
||
- [(1.1)](#1.1)
|
||
|
||
A [*glvalue*](#def:glvalue "7.2.1 Value category [basic.lval]") is an expression whose evaluation determines the identity of an object, function, or non-static data member[.](#1.1.sentence-1)
|
||
|
||
- [(1.2)](#1.2)
|
||
|
||
A [*prvalue*](#def:prvalue "7.2.1 Value category [basic.lval]") is an expression whose evaluation initializes an object
|
||
or computes the value of an operand of an operator,
|
||
as specified by the context in which it appears,
|
||
or an expression that has type cv void[.](#1.2.sentence-1)
|
||
|
||
- [(1.3)](#1.3)
|
||
|
||
An [*xvalue*](#def:xvalue "7.2.1 Value category [basic.lval]") is a glvalue that denotes an object whose resources can be reused (usually because it is near the end of its lifetime)[.](#1.3.sentence-1)
|
||
|
||
- [(1.4)](#1.4)
|
||
|
||
An [*lvalue*](#def:lvalue "7.2.1 Value category [basic.lval]") is a glvalue that is not an xvalue[.](#1.4.sentence-1)
|
||
|
||
- [(1.5)](#1.5)
|
||
|
||
An [*rvalue*](#def:rvalue "7.2.1 Value category [basic.lval]") is a prvalue or an xvalue[.](#1.5.sentence-1)
|
||
|
||
[2](#2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L160)
|
||
|
||
Every expression belongs to exactly one of the fundamental categories in this
|
||
taxonomy: lvalue, xvalue, or prvalue[.](#2.sentence-1)
|
||
|
||
This property of an expression is called
|
||
its [*value category*](#def:value_category "7.2.1 Value category [basic.lval]")[.](#2.sentence-2)
|
||
|
||
[*Note [1](#note-1)*:
|
||
|
||
The discussion of each built-in operator in[[expr.compound]](expr.compound "7.6 Compound expressions") indicates the category of the value it yields and the value categories
|
||
of the operands it expects[.](#2.sentence-3)
|
||
|
||
For example, the built-in assignment operators expect that
|
||
the left operand is an lvalue and that the right operand is a prvalue and yield an
|
||
lvalue as the result[.](#2.sentence-4)
|
||
|
||
User-defined operators are functions, and the categories of
|
||
values they expect and yield are determined by their parameter and return types[.](#2.sentence-5)
|
||
|
||
â *end note*]
|
||
|
||
[3](#3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L173)
|
||
|
||
[*Note [2](#note-2)*:
|
||
|
||
Historically, lvalues and rvalues were so-called
|
||
because they could appear on the left- and right-hand side of an assignment
|
||
(although this is no longer generally true);
|
||
glvalues are âgeneralizedâ lvalues,
|
||
prvalues are âpureâ rvalues,
|
||
and xvalues are âeXpiringâ lvalues[.](#3.sentence-1)
|
||
|
||
Despite their names, these terms apply to expressions, not values[.](#3.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[4](#4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L184)
|
||
|
||
[*Note [3](#note-3)*:
|
||
|
||
An expression is an xvalue if it is:
|
||
|
||
- [(4.1)](#4.1)
|
||
|
||
a move-eligible [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") ([[expr.prim.id.unqual]](expr.prim.id.unqual "7.5.5.2 Unqualified names"))
|
||
or [*splice-expression*](expr.prim.splice#nt:splice-expression "7.5.9 Expression splicing [expr.prim.splice]") ([[expr.prim.splice]](expr.prim.splice "7.5.9 Expression splicing")),
|
||
|
||
- [(4.2)](#4.2)
|
||
|
||
the result of calling a function, whether implicitly or explicitly,
|
||
whose return type is an rvalue reference to object type ([[expr.call]](expr.call "7.6.1.3 Function call")),
|
||
|
||
- [(4.3)](#4.3)
|
||
|
||
a cast to an rvalue reference to
|
||
object type ([[expr.type.conv]](expr.type.conv "7.6.1.4 Explicit type conversion (functional notation)"), [[expr.dynamic.cast]](expr.dynamic.cast "7.6.1.7 Dynamic cast"), [[expr.static.cast]](expr.static.cast "7.6.1.9 Static cast"), [[expr.reinterpret.cast]](expr.reinterpret.cast "7.6.1.10 Reinterpret cast"), [[expr.const.cast]](expr.const.cast "7.6.1.11 Const cast"), [[expr.cast]](expr.cast "7.6.3 Explicit type conversion (cast notation)")),
|
||
|
||
- [(4.4)](#4.4)
|
||
|
||
a subscripting operation with an xvalue array operand ([[expr.sub]](expr.sub "7.6.1.2 Subscripting")),
|
||
|
||
- [(4.5)](#4.5)
|
||
|
||
a class member access expression designating a non-static data member
|
||
of non-reference type
|
||
in which the object expression is an xvalue ([[expr.ref]](expr.ref "7.6.1.5 Class member access")), or
|
||
|
||
- [(4.6)](#4.6)
|
||
|
||
a .* pointer-to-member expression in which the first operand is
|
||
an xvalue and the second operand is a pointer to data member ([[expr.mptr.oper]](expr.mptr.oper "7.6.4 Pointer-to-member operators"))[.](#4.sentence-1)
|
||
|
||
In general, the effect of this rule is that named rvalue references are
|
||
treated as lvalues and unnamed rvalue references to objects are treated as
|
||
xvalues; rvalue references to functions are treated as lvalues whether named or not[.](#4.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[*Example [1](#example-1)*: struct A {int m;};
|
||
A&& operator+(A, A);
|
||
A&& f();
|
||
|
||
A a;
|
||
A&& ar = static_cast<A&&>(a);
|
||
|
||
The expressions f(), f().m, static_cast<A&&>(a), and a + a are xvalues[.](#4.sentence-3)
|
||
|
||
The expression ar is an lvalue[.](#4.sentence-4)
|
||
|
||
â *end example*]
|
||
|
||
[5](#5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L229)
|
||
|
||
The [*result*](#def:result,glvalue "7.2.1 Value category [basic.lval]") of a glvalue is the entity denoted by the expression[.](#5.sentence-1)
|
||
|
||
The [*result*](#def:result,prvalue "7.2.1 Value category [basic.lval]") of a prvalue
|
||
is the value that the expression stores into its context;
|
||
a prvalue that has type cv void has no result[.](#5.sentence-2)
|
||
|
||
A prvalue whose result is the value *V* is sometimes said to have or name the value *V*[.](#5.sentence-3)
|
||
|
||
The [*result object*](#def:result_object "7.2.1 Value category [basic.lval]") of a prvalue is the object initialized by the prvalue;
|
||
a prvalue that has type cv void has no result object[.](#5.sentence-4)
|
||
|
||
[*Note [4](#note-4)*:
|
||
|
||
Except when the prvalue is the operand of a [*decltype-specifier*](dcl.type.decltype#nt:decltype-specifier "9.2.9.6 Decltype specifiers [dcl.type.decltype]"),
|
||
a prvalue of object type always has a result object[.](#5.sentence-5)
|
||
|
||
For a discarded prvalue that has type other than cv void,
|
||
a temporary object is materialized; see [[expr.context]](expr.context "7.2.3 Context dependence")[.](#5.sentence-6)
|
||
|
||
â *end note*]
|
||
|
||
[6](#6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L246)
|
||
|
||
Whenever a glvalue appears as an operand of an operator that
|
||
requires a prvalue for that operand, the
|
||
lvalue-to-rvalue ([[conv.lval]](conv.lval "7.3.2 Lvalue-to-rvalue conversion")), array-to-pointer ([[conv.array]](conv.array "7.3.3 Array-to-pointer conversion")),
|
||
or function-to-pointer ([[conv.func]](conv.func "7.3.4 Function-to-pointer conversion")) standard conversions are
|
||
applied to convert the expression to a prvalue[.](#6.sentence-1)
|
||
|
||
[*Note [5](#note-5)*:
|
||
|
||
An attempt to bind an rvalue reference to an lvalue is not such a context; see [[dcl.init.ref]](dcl.init.ref "9.5.4 References")[.](#6.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[*Note [6](#note-6)*:
|
||
|
||
Because cv-qualifiers are removed from the type of an expression of
|
||
non-class type when the expression is converted to a prvalue, an lvalue
|
||
of type const int can, for example, be used where
|
||
a prvalue of type int is required[.](#6.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[*Note [7](#note-7)*:
|
||
|
||
There are no prvalue bit-fields; if a bit-field is converted to a
|
||
prvalue ([[conv.lval]](conv.lval "7.3.2 Lvalue-to-rvalue conversion")), a prvalue of the type of the bit-field is
|
||
created, which might then be promoted ([[conv.prom]](conv.prom "7.3.7 Integral promotions"))[.](#6.sentence-4)
|
||
|
||
â *end note*]
|
||
|
||
[7](#7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L267)
|
||
|
||
Unless otherwise specified ([[expr.reinterpret.cast]](expr.reinterpret.cast "7.6.1.10 Reinterpret cast"), [[expr.const.cast]](expr.const.cast "7.6.1.11 Const cast")),
|
||
whenever a prvalue
|
||
that is not the result of the lvalue-to-rvalue conversion ([[conv.lval]](conv.lval "7.3.2 Lvalue-to-rvalue conversion"))
|
||
appears as an operand of an operator,
|
||
the [temporary materialization conversion](conv.rval "7.3.5 Temporary materialization conversion [conv.rval]") is
|
||
applied to convert the expression to an xvalue[.](#7.sentence-1)
|
||
|
||
[8](#8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L275)
|
||
|
||
[*Note [8](#note-8)*:
|
||
|
||
The discussion of reference initialization in [[dcl.init.ref]](dcl.init.ref "9.5.4 References") and of
|
||
temporaries in [[class.temporary]](class.temporary "6.8.7 Temporary objects") indicates the behavior of lvalues
|
||
and rvalues in other significant contexts[.](#8.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[9](#9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L282)
|
||
|
||
Unless otherwise indicated ([[dcl.type.decltype]](dcl.type.decltype "9.2.9.6 Decltype specifiers")),
|
||
a prvalue shall always have complete type or the void type;
|
||
if it has a class type or (possibly multidimensional) array of class type,
|
||
that class shall not be an abstract class ([[class.abstract]](class.abstract "11.7.4 Abstract classes"))[.](#9.sentence-1)
|
||
|
||
A glvalue shall not have type cv void[.](#9.sentence-2)
|
||
|
||
[*Note [9](#note-9)*:
|
||
|
||
A glvalue can have complete or incomplete non-void type[.](#9.sentence-3)
|
||
|
||
Class and array prvalues can have cv-qualified types; other prvalues
|
||
always have cv-unqualified types[.](#9.sentence-4)
|
||
|
||
See [[expr.type]](expr.type "7.2.2 Type")[.](#9.sentence-5)
|
||
|
||
â *end note*]
|
||
|
||
[10](#10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L294)
|
||
|
||
An lvalue is [*modifiable*](#def:modifiable "7.2.1 Value category [basic.lval]") unless its type is const-qualified
|
||
or is a function type[.](#10.sentence-1)
|
||
|
||
[*Note [10](#note-10)*:
|
||
|
||
A program that attempts
|
||
to modify an object through a nonmodifiable lvalue or through an rvalue
|
||
is ill-formed ([[expr.assign]](expr.assign "7.6.19 Assignment and compound assignment operators"), [[expr.post.incr]](expr.post.incr "7.6.1.6 Increment and decrement"), [[expr.pre.incr]](expr.pre.incr "7.6.2.3 Increment and decrement"))[.](#10.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[11](#11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L303)
|
||
|
||
An object of dynamic type Tobj is[*type-accessible*](#def:type-accessible "7.2.1 Value category [basic.lval]") through a glvalue of type Tref if Tref is similar ([[conv.qual]](conv.qual "7.3.6 Qualification conversions")) to:
|
||
|
||
- [(11.1)](#11.1)
|
||
|
||
Tobj,
|
||
|
||
- [(11.2)](#11.2)
|
||
|
||
a type that is the signed or unsigned type corresponding to Tobj, or
|
||
|
||
- [(11.3)](#11.3)
|
||
|
||
a char, unsigned char, or std::byte type[.](#11.sentence-1)
|
||
|
||
If a program attempts to access ([[defns.access]](defns.access "3.1 access"))
|
||
the stored value of an object through a glvalue
|
||
through which it is not type-accessible,
|
||
the behavior is undefined[.](#11.sentence-2)[42](#footnote-42 "The intent of this list is to specify those circumstances in which an object can or cannot be aliased.")
|
||
|
||
If a program invokes
|
||
a defaulted copy/move constructor or copy/move assignment operator
|
||
for a union of type U with a glvalue argument
|
||
that does not denote an object of type cv U within its lifetime,
|
||
the behavior is undefined[.](#11.sentence-3)
|
||
|
||
[*Note [11](#note-11)*:
|
||
|
||
In C, an entire object of structure type can be accessed, e.g., using assignment[.](#11.sentence-4)
|
||
|
||
By contrast, C++ has no notion of accessing an object of class type
|
||
through an lvalue of class type[.](#11.sentence-5)
|
||
|
||
â *end note*]
|
||
|
||
[42)](#footnote-42)[42)](#footnoteref-42)
|
||
|
||
The intent of this list is to specify those circumstances in which an
|
||
object can or cannot be aliased[.](#footnote-42.sentence-1)
|