Search code examples
c++c++11rvalue

Exact difference between rvalue and lvalue


While I was reading http://thbecker.net/articles/rvalue_references/section_01.html, I got following snippiest.

// 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 error statement, while int* p1 = &foo(); is not an error. How later one is lvalue while first one is rvalue?


Solution

  • So we have two functions:

    int& foo();
    int foobar();
    
    • foo is a function returning lvalue-reference to int
    • foobar is a function returning int

    The function call expressions:

    foobar()
    foo()
    

    both have type int (references are removed from expressions, so foo() has type int and not lvalue-reference to int). The two expressions have different value categories:

    • foobar() is a prvalue (a function call to a function returning a non-reference is a prvalue)
    • foo() is an lvalue (a function call to a function returning an lvalue-reference is an lvalue)

    You can't take the address of an rvalue (a prvalue is a kind of rvalue), so &foobar() is not allowed.

    You can take the address of an lvalue so &foo() is allowed.