cpp/language/value category

Each C++ (an operator with its operands, a literal, a variable name, etc.) is characterized by two independent properties: a  and a value category. Each expression has some non-reference type, and each expression belongs to exactly one of the three primary value categories: prvalue, xvalue, and lvalue.


 * a glvalue (“generalized” lvalue) is an expression whose evaluation determines the identity of an object or function;
 * a prvalue (“pure” rvalue) is an expression whose evaluation
 * computes the value of an operand of a built-in operator (such prvalue has no result object), or
 * initializes an object (such prvalue is said to have a result object).
 * The result object may be a variable, an object created by, a temporary created by , or a member thereof. Note that non- expressions have a result object (the materialized temporary). Also, every class and array prvalue has a result object except when it is the operand of ;


 * an xvalue (an “eXpiring” value) is a glvalue that denotes an object whose resources can be reused;
 * an lvalue (so-called, historically, because lvalues could appear on the left-hand side of an assignment expression) is a glvalue that is not an xvalue;
 * an rvalue (so-called, historically, because rvalues could appear on the right-hand side of an assignment expression) is a prvalue or an xvalue.

Note: this taxonomy went through significant changes with past C++ standard revisions, see History below for details.

lvalue
The following expressions are lvalue expressions:
 * the name of a variable, a function, or a data member, regardless of type, such as or . Even if the variable's type is rvalue reference, the expression consisting of its name is an lvalue expression (but see Move-eligible expressions);
 * a function call or an overloaded operator expression, whose return type is lvalue reference, such as, , , or ;
 * ,, , and all other built-in expressions;
 * and, the built-in expressions;
 * , the built-in expression;
 * and, the built-in expressions;
 * , the expression, except where  is a member enumerator or a non-static member function, or where  is an rvalue and  is a non-static data member of object type;
 * , the built-in expression, except where  is a member enumerator or a non-static member function;
 * , the expression, where  is an lvalue and  is a pointer to data member;
 * , the built-in expression, where  is a pointer to data member;
 * , the built-in expression, where  is an lvalue;
 * , the expression for certain  and  (e.g., when both are lvalues of the same type, but see  for detail);
 * a, such as ;
 * a cast expression to lvalue reference type, such as or ;
 * a non-type of an lvalue reference type;

Properties:
 * Same as glvalue (below).
 * Address of an lvalue may be taken by built-in address-of operator: and  are valid expressions.
 * A modifiable lvalue may be used as the left-hand operand of the built-in assignment and compound assignment operators.
 * An lvalue may be used to ; this associates a new name with the object identified by the expression.

prvalue
The following expressions are prvalue expressions:
 * a (except for ), such as,  or ;
 * a function call or an overloaded operator expression, whose return type is non-reference, such as, , or ;
 * and, the built-in  expressions;
 * ,, , , and all other built-in expressions;
 * ,, , the built-in expressions;
 * ,, , and all other built-in expressions;
 * , the built-in expression;
 * , the expression, where  is a member enumerator or a non-static member function ;
 * , the built-in expression, where  is a member enumerator or a non-static member function ;
 * , the expression, where  is a pointer to member function ;
 * , the built-in expression, where  is a pointer to member function ;
 * , the built-in expression, where  is an rvalue;
 * , the expression for certain  and  (see  for detail);
 * a cast expression to non-reference type, such as, , or ;
 * the pointer;
 * an ;
 * a non-type of a scalar type;

Properties:
 * Same as rvalue (below).
 * A prvalue cannot be : the of the object it denotes is always the type of the expression.
 * A non-class non-array prvalue cannot be . (Note: a function call or cast expression may result in a prvalue of non-class cv-qualified type, but the cv-qualifier is generally immediately stripped out.)
 * A prvalue cannot have (except for type, see below, or when used in  specifier).
 * A prvalue cannot have or an array thereof.

xvalue
The following expressions are xvalue expressions:
 * , the expression, where  is an rvalue and  is a non-static data member of an object type;
 * , the expression, where  is an rvalue and  is a pointer to data member;
 * , the expression for certain  and  (see  for detail);

Properties:
 * Same as rvalue (below).
 * Same as glvalue (below).

In particular, like all rvalues, xvalues bind to rvalue references, and like all glvalues, xvalues may be, and non-class xvalues may be.

glvalue
A glvalue expression is either lvalue or xvalue.

Properties:
 * A glvalue may be implicitly converted to a prvalue with lvalue-to-rvalue, array-to-pointer, or function-to-pointer.
 * A glvalue may be : the of the object it identifies is not necessarily the static type of the expression.
 * A glvalue can have, where permitted by the expression.

rvalue
An rvalue expression is either prvalue or xvalue.

Properties:
 * Address of an rvalue cannot be taken by built-in address-of operator:, , , and  are invalid.
 * An rvalue can't be used as the left-hand operand of the built-in assignment or compound assignment operators.
 * An rvalue may be used to, in which case the lifetime of the object identified by the rvalue is until the scope of the reference ends.

Pending member function call
The expressions and, where  is a , and the expressions  and , where  is a , are classified as prvalue expressions, but they cannot be used to initialize references, as function arguments, or for any purpose at all, except as the left-hand argument of the function call operator, e.g..

Void expressions
Function call expressions returning, cast expressions to , and are classified as prvalue expressions, but they cannot be used to initialize references or as function arguments. They can be used in discarded-value contexts (e.g. on a line of its own, as the left-hand operand of the comma operator, etc.) and in the statement in a function returning. In addition, throw-expressions may be used as the second and the third operands of the.

Bit-fields
An expression that designates a (e.g., where  is an lvalue of type ) is a glvalue expression: it may be used as the left-hand operand of the assignment operator, but its address cannot be taken and a non-const lvalue reference cannot be bound to it. A const lvalue reference or rvalue reference can be initialized from a bit-field glvalue, but a temporary copy of the bit-field will be made: it won't bind to the bit-field directly.

{{rrev|since=c++11|

Move-eligible expressions
Although an expression consisting of the name of any variable is an lvalue expression, such expression may be move-eligible if it appears as the operand of
 * a statement
 * a statement
 * a expression

If an expression is move-eligible, it is treated for the purpose of   (thus it may select the ). See for details. }}

CPL
The programming language CPL was first to introduce value categories for expressions: all CPL expressions can be evaluated in "right-hand mode", but only certain kinds of expression are meaningful in "left-hand mode". When evaluated in right-hand mode, an expression is regarded as being a rule for the computation of a value (the right-hand value, or rvalue). When evaluated in left-hand mode an expression effectively gives an address (the left-hand value, or lvalue). "Left" and "Right" here stood for "left of assignment" and "right of assignment".

C
The C programming language followed a similar taxonomy, except that the role of assignment was no longer significant: C expressions are categorized between "lvalue expressions" and others (functions and non-object values), where "lvalue" means an expression that identifies an object, a "locator value".

C++98
Pre-2011 C++ followed the C model, but restored the name "rvalue" to non-lvalue expressions, made functions into lvalues, and added the rule that references can bind to lvalues, but only references to const can bind to rvalues. Several non-lvalue C expressions became lvalue expressions in C++.

C++11
With the introduction of move semantics in C++11, value categories were redefined to characterize two independent properties of expressions :
 * has identity: it's possible to determine whether the expression refers to the same entity as another expression, such as by comparing addresses of the objects or the functions they identify (obtained directly or indirectly);
 * can be moved from:, , or another function overload that implements move semantics can bind to the expression.

In C++11, expressions that:
 * have identity and cannot be moved from are called lvalue expressions;
 * have identity and can be moved from are called xvalue expressions;
 * do not have identity and can be moved from are called prvalue ("pure rvalue") expressions;
 * do not have identity and cannot be moved from are not used.

The expressions that have identity are called "glvalue expressions" (glvalue stands for "generalized lvalue"). Both lvalues and xvalues are glvalue expressions.

The expressions that can be moved from are called "rvalue expressions". Both prvalues and xvalues are rvalue expressions.

C++17
In C++17, was made mandatory in some situations, and that required separation of prvalue expressions from the temporary objects initialized by them, resulting in the system we have today. Note that, in contrast with the C++11 scheme, prvalues are no longer moved from.