Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ lvalues and rvalues

Tags:

c++

Ok, so I've been learning about lvalues and rvalues - could somebody well versed in C/C++ tell me if my thinking is correct?

Consider the code:

int i = 3;
int j = i;

Here we have two lvalues i and j, when i is assigned to j it becomes an implicit rvalue because a copy of i is stored in j. If however the code looked like:

int i = 3;
int j = &i;

Would both j and &i be lvalues because they are both physical addresses in memory? The way I understand it is that rvalues are temporary data, whereas lvalues have a physical/referenceable memory address.

Any clarification on this would be great!

like image 809
Halfpint Avatar asked Sep 14 '16 09:09

Halfpint


3 Answers

The variable i never stops being an lvalue. If you can apply the address-of operator to something (like you do in the second example) then it's an lvalue.

Also in the second example &i is a pointer to i, and has the type int*. You have a type mismatch there between the declaration of j and the value you want to initialize it with.

Lastly, while i by itself is a lvalue the expression &i is not an lvalue, because you can't apply the address-of operator to it (i.e you can't do &&i).

like image 143
Some programmer dude Avatar answered Oct 19 '22 14:10

Some programmer dude


Here we have two lvalues i and j

Yep

when i is assigned to j it becomes an implicit rvalue because a copy of i is stored in j

Not really, i is still an lvalue, but it's converted to an rvalue to read its value. This is called an lvalue-to-rvalue conversion. j is still an lvalue.

Would both j and &i be lvalues because they are both physical addresses in memory?

j is an lvalue, but &i is an rvalue; specifically a prvalue of type int*.

like image 28
TartanLlama Avatar answered Oct 19 '22 14:10

TartanLlama


Being an lvalue or an rvalue is a property of an expression. Generally, all expressions which constitute a non-const qualified identifier are modifiable lvalues:

int i = 5;
i; // the expression "i" is an lvalue and is modifiable

const int j = 3;
j; // the expression "j" is still an lvalue, but not modifiable

An lvalue expression (unless qualified with const) can be modified through any of the assignment, ++ or -- operators. You can also apply the & "address-of" operator on such an expression.

Some operators like the unary *, the array subscript operator [], and the . and -> operators also yield lvalues. This means that you can say, for example, *p = 3, or a[i] = 5, or b.c++ or &c->d.

On the other hand, expressions which are not lvalues are rvalues (they are temporary and cannot be modified). If you write something like 3 = 5 or 7++, the compiler will complain that the 3 and 7 subexpressions are not lvalues.

like image 43
Blagovest Buyukliev Avatar answered Oct 19 '22 15:10

Blagovest Buyukliev