Each expression in C is characterized by two properties: a type and its value category. There are two types of value categories in C, the lvalue
and rvalue
.
lvalue
:Simply put, lvalue
refers to any expression or object that can appear on the left side of the assignment operator.
lvalue
is an expression that refers to an lvalues
because you cannot assign anything to them.
lvalue
operands can be used in the following scenarios:
& *(address-of)
operator. (dot)
operatorRvalue
:rvalues
refers to anything that can be put on the right side of the assignment operator. To be more specific, rvalues
are expressions that do not represent a named storage in memory. This means that you cannot assign any value to them, and you cannot use &
with them or modify them in any way. rvalues
are often literals
or temporary objects that are created during the execution of a program.
Consider the following line of code:
int i = 100;
Here, the expression is assigning the value to variable i
. The variable i
is an area in the memory that can be referenced. In other words, we can use the name i
to refer to a specific memory location; this is what we call an lvalue
.
However, the value does not hold a named location in the memory, which means we cannot use it to store data or dereference it. For example, the following expression would not make much sense because does not refer to a memory location. Simply put, we have no way of accessing the memory address of this literal
. This literal
is an rvalue
.
100 = i; //
rvalues
are not necessarily always literals
; they can be temporary objects that are created when a function returns a value as well. Let’s see an example of temporary objects as rvalues
.
Suppose we have a function:
int temp_func()
{
return 10;
}
We can assign the value returned by the function to a variable like this:
int x = temp_func();
The returned value of the function is stored in the memory in a temporary variable. However, we have no means of accessing that value or its memory location, making the temporary value an rvalue
.
As with all rvalues
, if we try to assign some value to a function that returns a value,
we will get an error.
temp_funct() = 100; // Will give an lvalue error
Generally speaking, it is safe to assume that rvalues
appear on the right side and lvalues
appear on the left side of an expression. However, the important distinction between them is not where they appear in an expression, but rather their properties as discussed above. For example, an lvalue
can also be used on the right side of an expression:
int i = 10;
int j = i;
Here, the variable i
is used on the right-hand side of the assignment operator. This does not make i
an rvalue
just on the basis of where it appears in the expression. It is still an lvalue
since the variable i
refers to named storage in memory, meaning it can be referenced using the &
operator and works with the pre and post-increment and decrement operators.
Free Resources