Search code examples
c++c++11rvaluelvalue

Why are literals and temporary variables not lvalues?


I've read that lvalues are "things with a defined storage location".

And also that literals and temporaries variables are not lvalues, but no reason is given for this statement.

Is it because literals and temporary variables do not have defined storage location? If yes, then where do they reside if not in memory?

I suppose there is some significance to "defined" in "defined storage location", if there is (or is not) please let me know.


Solution

  • And also that literals and temporaries variables are not lvalues, but no reason is given for this statement.

    This is true for all temporaries and literals except for string literals. Those are actually lvalues (which is explained below).

    Is it because literals and temporaries variables do not have defined storage location? If yes, then where do they reside if not in memory?

    Yes. The literal 2 doesn't actually exist; it is just a value in the source code. Since it's a value, not an object, it doesn't have to have any memory associated to it. It can be hard coded into the assembly that the compiler creates, or it could be put somewhere, but since it doesn't have to be, all you can do is treat it as a pure value, not an object.

    There is an exemption though and that is string literals. Those actually have storage since a string literal is an array of const char[N]. You can take the address of a string literal and a string literal can decay into a pointer, so it is an lvalue, even though it doesn't have a name.

    Temporaries are also rvalues. Even if they exist as objects, their storage location is ephemeral. They only last until the end of the full expression they are in. You are not allowed to take their address and they also do not have a name. They might not even exist: for instance, in

    Foo a = Foo();
    

    The Foo() can be removed and the code semantically transformed to

    Foo a(); // you can't actually do this since it declares a function with that signature.
    

    so now there isn't even a temporary object in the optimized code.