@Yardanico's answer is of course correct, but I want to try an example, which I think should be clearer, and also because I'd like to be corrected by someone who knows better if I'm wrong:
int a = 3 + 4;
const int b = dosomething();
int c = a + b;
a is an l-value, which means it can appear on the l eft side of an assignment. L-values involve storage. On the r ight hand side is 3+4, which simplifies to 7. Neither 3, 4, nor 7 persists beyond this expression, so they are r-values. You can't assign to any of these three values; 7 = 3+4 is a compile-time error.
b is also an l-value, though you can assign to it only once. The value returned by dosomething() is an r-value. You cannot compile dosomething() = 5.
In the third assignment, a, b, and c are all l-values, even though a and b appear on the right-hand side of an assignment, because you could assign to them (at least once) and (more importantly) their values persist beyond the assignment.
Now, suppose we have the following:
int *dosomething() {
int *d = (int *)malloc(sizeof(int));
return d;
}
const int e = *dosomething();
int f = *dosomething() = 5;
printf("%d %d\n", e, f);
In this case, the return value of dosomething() is a pointer, so we can redirect to the underlying integer and assign 5 to it. So, while dosomething() is itself an r-value (the pointer is invalid after the assignment completes, and you would not be allowed to attempt to assign to it), *dosomething() is an l-value.@cantanima,
int f = *dosomething() = 5;
This spins my head. What on earth is this ?
int f = *dosomething() ;
I can understand this. But this part is not digesting for me -
dosomething() = 5;
You mean this function is behaving like a variable or a storage container ?I can understand this. But this part is not digesting for me -
dosomething() = 5;
You mean this function is behaving like a variable or a storage container ?
That assignment is invalid, and even a half-competent C/C++ compiler will report an error. The values that functions return are r-values; they disappear immediately after the statement. When I write dosomething() (without a star) I am referring to the function's return value, an r-value.
On the other hand, in the second version,
*dosomething() = 5;
is OK, because here dosomething() returns a pointer to integer. That's still an r-value, but in the assignment I wrote, *dosomething(). C's order of operations dereferences the pointer, so that now you're dealing with memory storage; i.e., an l-value, so that *dosomething() = 5 is legitimate and makes sense.
Another way of saying this is that
f = *dosomething() = 5;
is equivalent to
{
int *tmp = dosomething();
*tmp = 5;
f = *tmp;
}
After the right-hand brace, tmp no longer exists, but f has the value 5. Does that help?