Basics and important facts:
In The C Programming Language (Prentice-Hall, 1988), they wrote “An object is a manipulatable
region of storage; an lvalue is an expression referring to an object….The name ‘lvalue’ comes
from the assignment expression E1 = E2 in which the left operand E1 must be an lvalue expression.”
The C++ Standard does use the term rvalue, defining it indirectly with this sentence: “Every expression
is either an lvalue or an rvalue.” So an rvalue is any expression that is not an lvalue.
An identifier that refers to an object is an lvalue, but an identifier that names an enumeration constant
is an rvalue.
As I understand rvalue is just a value.
You can’t use an rvalue as an lvalue, you can use an lvalue as an rvalue.
Important terminology in c++ std and which compiler uses when using lvalue as an rvalue is lvalue-to-rvalue
Compiler does this lvalue to rvalue conversion to obtain the value stored in the object that lvalue referes to.
& (address-of) operator requires an lvalue as its operand, Although the unary & requires an lvalue as its operand,
it’s result is an rvalue and so expression &n = p; // error: &n is an rvalue
In contrast to unary &, unary * produces an lvalue as its result. that is why expression *(p + 1) = 4; // ok
Conceptually, an rvalue is just a value; it doesn’t refer to an object. In practice, it’s not that an rvalue
can’t refer to an object. It’s just that an rvalue doesn’t necessarily refer to an object.
Therefore, both C and C++ insist that you program as if rvalues don’t refer to objects.
In C++, rvalues of a class type do refer to objects, but they still aren’t lvalues.
Although lvalues do designate objects, not all lvalues can appear as the left operand of an assignment.
In C++ every expression yields either an lvalue or an rvalue and accordingly every expression
is called either an lvalue or an rvalue expression.
An example of an lvalue is an identifier. As a further example, a reference to an object is an lvalue. ( Is it named reference)
An intuitive approach would be to think of expressions as functions and then an lvalue can be thought as the result of a
function returning a reference.
The subscript operator is a function of the form T& operator(T*, ptrdiff_t) and therefore A is an lvalue where A is of array type.
The dereference operator is a function of the form T& operator*(T*) and hence *p is an lvalue where p is of pointer type.
The negate operator is of the form T operator-(T) and therefore -x is an rvalue.
An lvalue refers to a defined region of storage.
ImP: Non-class rvalues are non-modifiable. but this is not the case with user types.
A class rvalue can be used to modify an object through its member functions.
Non Class rvalue
Non-class rvalues do not have the same qualities as the user type rvalues
Non-class rvalues are not modifiable, nor can have cv-qualified types (the cv-qualifications are ignored).
On the contrary, the class rvalues are modifiable and can be used to modify an object via its member functions.
Non Modifiable lvalue, const reference is a good example of this.
A reference can be declared without an initializer:
When it is used in a parameter declaration
In the declaration of a return type for a function call
In the declaration of class member within its class declaration
When the extern specifier is explicitly used
You cannot have references to any of the following:
Arrays of references
Pointers to references
Suppose a reference r of type T is initialized by an expression e of type U.
The reference r is bound directly to e if the following statements are true:
Expression e is an lvalue
T is the same type as U, or T is a base class of U
T has the same, or more, const or volatile qualifiers than U
The reference r is also bound directly to e if e can be implicitly converted to a type such that the previous list of statements is true.
More points :
Every expression in C and C++ is either an lvalue or an rvalue. An lvalue is an expression that designates
(refers to) an object. Every lvalue is, in turn, either modifiable or non-modifiable. An rvalue is any expression
that isn’t an lvalue. Operationally, the difference among these kinds of expressions is this:
A modifiable lvalue is addressable (can be the operand of unary &) and assignable (can be the left operand of =).
A non-modifiable lvalue is addressable, but not assignable.
An rvalue is neither addressable nor assignable. What does it really mean? I think about this as r values does not have defined address in RAM (our physical memory ) otherwise it would be addressable.
Note in C++, All this applies only to rvalues of a non-class type.
Can we print an class type lvalue. I think no. We can only print non class type lvalue.
Reference of a pointer:
The ampersand symbol & is used in C++ as a reference declarator in addition to being the address operator.
The meanings are related but not identical.
int &rTarg = target; // rTarg is a reference to an integer.
// The reference is initialized to refer to target.
void f(int*& p); // p is a reference to a pointer
If you take the address of a reference, it returns the address of its target.
Using the previous declarations, &
rTarg is the same memory address as &target.
Pointer type: I guess it is an rvalue …Not necesarity.
a * b => rvalue
An lvalue is an expression that refers to a memory location and allows us to take the
address of that memory location via the & operator. An rvalue is an expression that is not an lvalue.
By looking at the syntax, What a copy assignment operator returns? I think it returns an lvalue
A& A::operator(A const & rhs).
Concept of named address, alias or ref to pointer:
http://ieng9.ucsd.edu/~cs30x/Non-modifiable%20Lvalues.htm => Very good explanation
search in google: What const Really Means