Expressions are categorized according to the taxonomy in Figure [fig:categories].
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 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.
[ 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 ] 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 Clause [expr] 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 ]
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 Clause [expr]. — end note ] The result of a glvalue is the entity denoted by the expression.
[ Note: Whenever a glvalue appears in a context where a prvalue is expected, the glvalue is converted to a prvalue; see [conv.lval], [conv.array], and [conv.func]. An attempt to bind an rvalue reference to an lvalue is not such a context; see [dcl.init.ref]. — end note ] [ Note: There are no prvalue bit-fields; if a bit-field is converted to a prvalue, a prvalue of the type of the bit-field is created, which might then be promoted. — end note ]
[ Note: Whenever a prvalue appears in a context where a glvalue is expected, the prvalue is converted to an xvalue; see [conv.rval]. — end note ]
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. See Clause [expr]. — 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:56
the dynamic type of the object,
a cv-qualified version of the dynamic type of the object,
a type similar 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.