25

Possible Duplicate:
What are rvalues, lvalues, xvalues, glvalues, and prvalues?

The C++ Standard, mostly in Chapter 5, entitled Expressions, defines which expressions are lvalues and which are rvalues. I have read that chapter, and I believe I can correctly distinguish between lvalues and rvalues.

However before I had read good C++ books and/or the standard, I used to think that an lvalue is something that can stand on the left side of an assignment, and an rvalue is something which cannot. Obviously there are numerous counterexamples to this naive definition. Some time later I thought that an lvalue is something which has an address, and an rvalue is something which doesn't. This too, seems to have counterexamples in the form of, say, some temporary objects, which, obviously, do have an address.

A friend of mine asked me what is an lvalue and what is an rvalue. I told him approximately what it is, he demanded a more complete answer. I told him to go read the standard. He refused to molest his brains and said he was sure there must be some necessary and sufficient condition for something to be an lvalue.

Is there?

For example, an lvalue is something that a non-const reference can bind to. But this one isn't really satisfactory. I am looking for something more obvious, something which is easy to explain, without resorting to considering each expression type...

I hope the question was clear.

Community
  • 1
  • 1
Armen Tsirunyan
  • 130,161
  • 59
  • 324
  • 434
  • I believe that you try too much to have an exclusive definition for each of them. There are some elements that can be both lvalues and rvalues. `int a; int b; b = 4; a = b;` – dee-see Jun 18 '11 at 17:48
  • There was a similar question up a while ago, and the basic gist was that functions that return structs could also be assigned to. So you can do something like foo() = whatever. Here's the question: http://stackoverflow.com/questions/6111905/c-is-return-value-a-l-value (Moved from the low rated answer below) – Mike Bailey Jun 18 '11 at 17:53
  • Or: [What are rvalues, lvalues, xvalues, glvalues, and prvalues?](http://stackoverflow.com/questions/3601602/what-are-rvalues-lvalues-xvalues-glvalues-and-prvalues) – James McNellis Jun 18 '11 at 17:53
  • 1
    I am disappointed that this question is deemed a duplicate to any of the suggested links. – Armen Tsirunyan Jun 18 '11 at 18:09
  • 5
    I don't think you can get a much simpler approximation of what they are than ["lvalues name objects that persist beyond a single expression... rvalues are temporaries that evaporate at the end of the full-expression in which they live"](http://blogs.msdn.com/b/vcblog/archive/2009/02/03/rvalue-references-c-0x-features-in-vc10-part-2.aspx) – James McNellis Jun 18 '11 at 18:30
  • @James: I actually like this definition – Armen Tsirunyan Jun 18 '11 at 18:34
  • An lvalue is an expression that you can apply the `&` operator to. – fredoverflow Jun 19 '11 at 00:11
  • @Fred: You can apply & to temporary objects, too – Armen Tsirunyan Jun 19 '11 at 10:51
  • @Armen: Temporary objects can be denoted by both lvalues and rvalues, but `&expression` only works if `expression` is an lvalue. You cannot say `&(string("hello"))`, because `string("hello")` is an rvalue. You can however say `&variable` if `variable` is an lvalue reference to const or an rvalue reference that is bound to the temporary object `string("hello")`. – fredoverflow Jun 19 '11 at 11:19

4 Answers4

16

Pretty simply, an rvalue is when the expression result will not survive past the end of said expression. An lvalue will. This basic principle is what enables move semantics and rvalue references- that you can modify them without issue, because you know that object's life is over.

Puppy
  • 144,682
  • 38
  • 256
  • 465
  • This is not true - you can have an lvalue that designates a temporary object, and an rvalue that designates an object of static storage duration, (among other possibilities) – M.M Aug 30 '17 at 21:08
  • @M.M, could you please provide examples of these two cases? – user51462 Jul 15 '23 at 03:14
  • @user51462 for the first one, do `*this` in a member function called on a temporary object. For the second one, `std::move(x)` if `x` is a static object – M.M Jul 16 '23 at 12:44
12

I've found considering lvalues as "things with names" to be the most useful simplification. The expression ++x is an lvalue, with the name being x. By contrast, rvalue are "things without names". x++ is an rvalue, because it yields some unnamed value.

Dennis Zickefoose
  • 10,791
  • 3
  • 29
  • 38
  • +1 for actually reading and understanding my question. But int& f() {int* p = new int; return *p;} What's the name of f()? :) – Armen Tsirunyan Jun 18 '11 at 18:13
  • 1
    @Armen: 0x830D2CFF, or whatever address `new int` happens to yield. I never said you needed to have access to the name :-P – Dennis Zickefoose Jun 18 '11 at 18:17
  • @Dennis: In this case can't we think of a temporaty object as one that has a name(bacause it has an address)? – Armen Tsirunyan Jun 18 '11 at 18:19
  • But seriously, you aren't going to get a simple easy to grok answer that covers all use cases. If you want, combine this with the "has an address" answers, and you'll probably be pretty close, provided you remember that temporaries need not have an address. – Dennis Zickefoose Jun 18 '11 at 18:21
  • @Armen: Temporaries need not have an address. `int f();` If your system's calling convention allows that function to return its value in a register instead of on the stack, what is the address of the temporary it yields? – Dennis Zickefoose Jun 18 '11 at 18:23
  • 1
    http://stackoverflow.com/questions/6162226/what-rvalues-have-names (rvalues can have names (many have), and lvalues can miss a name (many do miss)). – Johannes Schaub - litb Jun 18 '11 at 19:11
  • 2
    @Dennis, `f()` is an rvalue, but not a temporary. In fact it can be argued that every temporary has an address. Every temporary is an object, and an object is a region of storage. But still there are no temporaries in C++ that have a name (but not every nameless object is a temporary!). – Johannes Schaub - litb Jun 18 '11 at 21:01
  • @Johannas: I said it was a simplification, leave me alone :-P Joking, I appreciate the clarifications. I was a little loose with my terminology (specifically, an informal meaning for name) but I don't see how that function doesn't yield a temporary object? – Dennis Zickefoose Jun 18 '11 at 22:02
0

An l-value is something that refers to a memory location. this is the simplest thing i could say.An r-value can be an l-value An r-value is just the result of an expression or a constant

lovesh
  • 5,235
  • 9
  • 62
  • 93
  • 5
    "An r-value can be an l-value" No; an expression is either an rvalue or an lvalue (in C++98); an lvalue is implicitly convertible to an rvalue. – James McNellis Jun 18 '11 at 17:51
0

may be you are just a little confused between modifiable lvalue and non-lvalues. rvalues can be lvalues or non-lvalues.the term modifiable lvalue is used after the introduction of const modifier(see wikipedia entry on values) in C++ every expression returns an lvalue,rvalue or no value.when an lvalue appears as a rvalue it is implicitly convertedto a rvalue(see IBM on value types)

jemmanuel
  • 466
  • 4
  • 13
  • 1
    No, I don't think I am confused between these notions – Armen Tsirunyan Jun 18 '11 at 17:59
  • The const qualifier is not required to demonstrate a non-modifiable lvalue: `int x[3];` here, `x` is a non-modifiable lvalue. "rvalues can be lvalues or non-lvalues" This is incorrect: no rvalue is an lvalue. Every expression is _either_ an lvalue or an rvalue. There is an implicit conversion that permits an lvalue to be converted to an rvalue. – James McNellis Jun 18 '11 at 18:00