[basic.lval] (original) (raw)

7 Expressions [expr]

7.2 Properties of expressions [expr.prop]

7.2.1 Value category [basic.lval]

Expressions are categorized according to the taxonomy in Figure 1.

categories expression expression glvalue glvalue expression->glvalue rvalue rvalue expression->rvalue lvalue lvalue glvalue->lvalue xvalue xvalue glvalue->xvalue rvalue->xvalue prvalue prvalue rvalue->prvalue

Figure 1: Expression category taxonomy [fig:basic.lval]

Every expression belongs to exactly one of the fundamental classifications in this taxonomy: lvalue, xvalue, or prvalue.

This property of an expression is called its value category.

[Note 1:

The discussion of each built-in operator in[expr.compound] indicates the category of the value it yields and the value categories of the operands it expects.

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.

User-defined operators are functions, and the categories of values they expect and yield are determined by their parameter and return types.

— _end note_]

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

Despite their names, these terms classify expressions, not values.

— _end note_]

[Note 3:

An expression is an xvalue if it is:

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.

— _end note_]

[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 + aare xvalues.

The expression ar is an lvalue.

— _end example_]

The result of a glvalue is the entity denoted by the expression.

The result of a prvalue is the value that the expression stores into its context; a prvalue that has type cv void has no result.

A prvalue whose result is the value _V_is sometimes said to have or name the value V.

The result object of a prvalue is the object initialized by the prvalue; a non-discarded prvalue that is used to compute the value of an operand of a built-in operator or a prvalue that has type cv voidhas no result object.

[Note 4:

Except when the prvalue is the operand of a decltype-specifier, a prvalue of class or array type always has a result object.

For a discarded prvalue that has type other than cv void, a temporary object is materialized; see [expr.context].

— _end note_]

Whenever a glvalue appears as an operand of an operator that expects a prvalue for that operand, thelvalue-to-rvalue, array-to-pointer, or function-to-pointer standard conversions are applied to convert the expression to a prvalue.

[Note 5:

An attempt to bind an rvalue reference to an lvalue is not such a context; see [dcl.init.ref].

— _end note_]

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

— _end note_]

[Note 7:

There are no prvalue bit-fields; if a bit-field is converted to a prvalue ([conv.lval]), a prvalue of the type of the bit-field is created, which might then be promoted ([conv.prom]).

— _end note_]

Whenever a prvalue appears as an operand of an operator that expects a glvalue for that operand, thetemporary materialization conversion is applied to convert the expression to an xvalue.

The discussion of reference initialization in [dcl.init.ref] and of temporaries in [class.temporary] indicates the behavior of lvalues and rvalues in other significant contexts.

Unless otherwise indicated ([dcl.type.decltype]), a prvalue shall always have complete type or the void type; if it has a class type or (possibly multi-dimensional) array of class type, that class shall not be an abstract class ([class.abstract]).

A glvalue shall not have type cv void.

[Note 8:

A glvalue can have complete or incomplete non-void type.

Class and array prvalues can have cv-qualified types; other prvalues always have cv-unqualified types.

— _end note_]

An lvalue is modifiable unless its type is const-qualified or is a function type.

If a program attempts to accessthe stored value of an object through a glvalue whose type is not similar to one of the following types the behavior is undefined:55

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.

[Note 10:

Unlike in C, C++ has no accesses of class type.

— _end note_]