简体   繁体   中英

C++ lvalues and rvalues

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!

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 (ie you can't do &&i ).

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.

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* .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM