Skip to content

Latest commit

 

History

History
119 lines (99 loc) · 4.43 KB

File metadata and controls

119 lines (99 loc) · 4.43 KB
title Value Categories: Lvalues and Rvalues (Visual C++) | Microsoft Docs
ms.custom
ms.date 11/04/2016
ms.reviewer
ms.suite
ms.technology
cpp-language
ms.tgt_pltfrm
ms.topic language-reference
dev_langs
C++
helpviewer_keywords
R-values
L-values
ms.assetid a8843344-cccc-40be-b701-b71f7b5cdcaf
caps.latest.revision 14
author mikeblome
ms.author mblome
manager ghogen
translation.priority.ht
cs-cz
de-de
es-es
fr-fr
it-it
ja-jp
ko-kr
pl-pl
pt-br
ru-ru
tr-tr
zh-cn
zh-tw

Lvalues and Rvalues (Visual C++)

Every C++ expression has a type, and belongs to a value category. The value categories are the basis for rules that compilers must follow when creating, copying, and moving temporary objects during expression evaluation. In C++17 (Visual Studio version 15.3 and later) the rules were restated to ensure that all compilers behave identically by not creating objects unless they are actually required. The new specified behavior is called "guaranteed copy elision." It helps to make your code more portable and efficient and eliminates the need to provide copy and move constructors for types that never use them.

The C++17 standard defines expression value categories as follows:

  • 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 (8.3.2) yield xvalues, such as a call to a function whose return type is an rvalue reference or a cast to an rvalue reference type. ]
  • An lvalue is a glvalue that is not an xvalue.
  • An rvalue is a prvalue or an xvalue.

Examples of lvalue expressions include variable names, including const variables, array elements, bit-fields, unions, and class members. Examples of rvalue expressions include literals, function calls, and temporary objects that are created during expression evalution but accessible only by the compiler.

The following example demonstrates several correct and incorrect usages of lvalues and rvalues:

// lvalues_and_rvalues2.cpp  
int main()  
{  
   int i, j, *p;  
  
   // Correct usage: the variable i is an lvalue and the literal 7 is a prvalue.  
   i = 7;  
  
   // Incorrect usage: The left operand must be an lvalue (C2106).  `j * 4` is a prvalue.
   7 = i; // C2106  
   j * 4 = 7; // C2106  
  
   // Correct usage: the dereferenced pointer is an lvalue.  
   *p = i;   
  
   const int ci = 7;  
   // Incorrect usage: the variable is a non-modifiable lvalue (C3892).  
   ci = 9; // C3892  
  
   // Correct usage: the conditional operator returns an lvalue.  
   ((i < 3) ? i : j) = 7;  
}  

Note

The examples in this topic illustrate correct and incorrect usage when operators are not overloaded. By overloading operators, you can make an expression such as j * 4 an lvalue.

The following example shows the new behavior for guaranteed copy elision. Note that construction from temporary objects succeeds in both cases despite the absence of a move constructor.

#include <iostream>
#include <string>

using namespace std;

struct S {
	S(int) { cout << "S(int)" << endl; }
	S(S&) = delete;
	S(S&&) = delete; // { cout << "move" << endl; }
	///...
};

S make_s() 
{
	// Return value initialized directly at call site.
	// In Visual Studio 2015 this does not compile due to deleted move ctor.
	return S(42);
}


int main()
{
	auto nm = make_s(); 
	S x4 = 5; // Construct from an rvalue.
}

The program produces this output:

S(int)
S(int)

The terms lvalue and rvalue are often used when you refer to object references. For more information about references, see Lvalue Reference Declarator: & and Rvalue Reference Declarator: &&.

See Also

Basic Concepts
Lvalue Reference Declarator: &
Rvalue Reference Declarator: &&