8 Expressions [expr]

8.2 Properties of expressions [expr.prop]

8.2.1 Value category [basic.lval]

Expressions are categorized according to the taxonomy in Figure [fig:categories].
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
  • A glvalue is an expression whose evaluation determines the identity of an object, bit-field, or function.
  • A prvalue is an expression whose evaluation initializes an object or a bit-field, or computes the value of the operand of an operator, as specified by the context in which it appears.
  • An xvalue is a glvalue that denotes an object or bit-field whose resources can be reused (usually because it is near the end of its lifetime).
    [Example
    :
    Certain kinds of expressions involving rvalue references ([dcl.ref]) yield xvalues, such as a call to a function whose return type is an rvalue reference or a cast to an rvalue reference type.
    end example
    ]
  • An lvalue is a glvalue that is not an xvalue.
  • An rvalue is a prvalue or an xvalue.
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
:
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
:
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
:
An expression is an xvalue if it is:
  • the result of calling a function, whether implicitly or explicitly, whose return type is an rvalue reference to object type,
  • a cast to an rvalue reference to object type,
  • a class member access expression designating a non-static data member of non-reference type in which the object expression is an xvalue, or
  • a .* pointer-to-member expression in which the first operand is an xvalue and the second operand is a pointer to data member.
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
:
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.
The expression ar is an lvalue.
end example
]
The result of a prvalue is the value that the expression stores into its context.
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 prvalue that is used to compute the value of an operand of an operator or that has type cv void has no result object.
[Note
:
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, a temporary object is materialized; see [expr.prop].
end note
]
The result of a glvalue is the entity denoted by the expression.
Whenever a glvalue expression appears as an operand of an operator that expects a prvalue for that operand, the lvalue-to-rvalue, array-to-pointer, or function-to-pointer standard conversions are applied to convert the expression to a prvalue.
[Note
:
An attempt to bind an rvalue reference to an lvalue is not such a context; see [dcl.init.ref].
end note
]
[Note
:
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 expression of type const int can, for example, be used where a prvalue expression of type int is required.
end note
]
[Note
:
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 expression appears as an operand of an operator that expects a glvalue for that operand, the temporary 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 ([expr.call]), a prvalue shall always have complete type or the void type.
A glvalue shall not have type cv void.
[Note
:
A glvalue may 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.
[Note
:
A program that attempts to modify an object through a nonmodifiable lvalue expression or through an rvalue expression is ill-formed ([expr.ass], [expr.post.incr], [expr.pre.incr]).
end note
]
If a program attempts to access the stored value of an object through a glvalue of other than one of the following types the behavior is undefined:63
  • the dynamic type of the object,
  • a cv-qualified version of the dynamic type of the object,
  • a type similar (as defined in [conv.qual]) to the dynamic type of the object,
  • a type that is the signed or unsigned type corresponding to the dynamic type of the object,
  • a type that is the signed or unsigned type corresponding to a cv-qualified version of the dynamic type of the object,
  • an aggregate or union type that includes one of the aforementioned types among its elements or non-static data members (including, recursively, an element or non-static data member of a subaggregate or contained union),
  • a type that is a (possibly cv-qualified) base class type of the dynamic type of the object,
  • a char, unsigned char, or std​::​byte type.
The intent of this list is to specify those circumstances in which an object may or may not be aliased.