Exact difference between rvalue and lvalue

While I was reading http://thbecker.net/articles/rvalue_references/section_01.html , I got the latest information.

// lvalues: // int i = 42; i = 43; // ok, i is an lvalue int& foo(); foo() = 42; // ok, foo() is an lvalue int* p1 = &foo(); // ok, foo() is an lvalue // rvalues: // int foobar(); int j = 0; j = foobar(); // ok, foobar() is an rvalue int* p2 = &foobar(); // error, cannot take the address of an rvalue j = 42; // ok, 42 is an rvalue 

Why int * p2 = & foobar (); is an error expression, whereas int * p1 = & foo (); not a mistake. How later is one lvalue and the first rvalue?

Thank you in advance

+6
source share
2 answers

So, we have two functions:

 int& foo(); int foobar(); 
  • foo is a function returning an lvalue-reference value for int
  • foobar is a function that returns int

Function call expressions:

 foobar() foo() 

both are of type int (references are removed from expressions, so foo() is of type int , not lvalue-reference to int ). Two expressions have different categories of values:

  • foobar() is a prvalue (a function call for a function returning a non-reference is prvalue)
  • foo() - lvalue value (function call for function returning lvalue-reference is lvalue)

You cannot take the address of rvalue (prvalue is a kind of rvalue), therefore &foobar() not allowed.

You can take the lvalue address, therefore &foo() allowed.

+4
source

Suppose we have an example of the code shown below in C. Will it compile? How do lvalues ​​and rvalues ​​work in this problem?

 #define X 8 int main(void) { ++X; // will this line compile? return 0; } 

The concepts of lvalues ​​and rvalues ​​should be explained a bit in order to really understand the above code and the problem statement. Before we continue, you should note that the definition of lvalues ​​and rvalues ​​presented here is not accurate, since even the C standards themselves are rather vague in definition.

Difference between values ​​and lvalues

An object is a region of memory that can be checked, but not necessarily changed. Lvalue is an expression that refers to such an object. The term lvalue originally referred to objects that appear on the left (hence the "l") side of the expression. This definition is no longer applicable, since any const-qualified type is also considered an lvalue, but it can never appear on the left side of the assignment operator, because it cannot be changed. Thus, the term “lvalue modifiable value” was created to mean the lvalue value that can be changed, and the type corresponding to const does not fall into this category.

The value r is any expression that has a value but cannot have a value assigned to it. You can also say that rvalue is any expression that is not an lvalue. An example of rvalue would be a literal constant - something like 8 'or 3.14'. Thus, it is obvious that the value 8 'in the above code is an rvalue.

Using our understanding of lvalues ​​and rvalues ​​to answer a question

Now let's try to solve the problem. Strictly speaking, the operand of the increment operator of a prefix (or postfix) must be a modifiable value of lvalue. So, what is the operand of the prefix increment operator in our code above?

Since X is a macro, the above expression will expand to "++ 8" after starting the preprocessor. This means that "8" is the operand of the prefix increment operator. And since 8 is an rvalue value, it cannot be used as an argument to "++". This, in turn, means that the code above will not compile.

+6
source

Source: https://habr.com/ru/post/948290/


All Articles