Reputation: 5300
Here are the few definitions I read about lvalues
Expressions which can be used with & operator. i.e if &(expression) is not an error, then the expression is an lvalue
Expression which results in objects that are not temporary
lvalue expressions can be used on both RHS and LHS of = operator
rvalue expressions can be used only on RHS
Please correct if wrong
Here's the question
I read ++x is a lvalue and x++ is an rvalue
int i = 0;
printf("%p",(void*)&++i);
If so, why is this an error?
If lvalue expressions can be used on lhs
int i = 0;
++i = 10;
Why can't I use the above statement??Both the above are resulting in errors
Update: Both the above statements are fine in C++
Upvotes: 3
Views: 528
Reputation: 10688
++i
is an lvalue
only in C++, in C it's an rvalue
(called value of an expression in the C standard) which cannot be assigned.
Upvotes: 3
Reputation: 213678
The (rather vague) formal definition from C11:
(emphasis in bold font was added by me)
6.3.2.1 Lvalues, arrays, and function designators
An lvalue is an expression (with an object type other than void) that potentially designates an object (64); if an lvalue does not designate an object when it is evaluated, the behavior is undefined. When an object is said to have a particular type, the type is specified by the lvalue used to designate the object. A modifiable lvalue is an lvalue that does not have array type, does not have an incomplete type, does not have a const-qualified type, and if it is a structure or union, does not have any member (including, recursively, any member or element of all contained aggregates or unions) with a const-qualified type.
Foot note (not normative) with further explanation:
64) The name "lvalue" comes originally from the assignment expression E1 = E2, in which the left operand E1 is required to be a (modifiable) lvalue. It is perhaps better considered as representing an object "locator value". What is sometimes called "rvalue" is in this International Standard described as the "value of an expression".
So an lvalue must be something that "potentially" designates an object. Whatever "potentially" means is open for personal interpretation...
Despite the above foot note, the C standard lacks a formal definition of a rvalue. Ironically, the only place in the whole standard mentioning rvalue is that one foot note.
In your case, neither ++i nor i++ designates an actual object, so neither of them are lvalues. They are rather rvalues.
Upvotes: 1
Reputation: 22241
I thought that this question would be closed, and I only left a comment. What a big mistake;)
In C (the question's tag is C) ++i operator does "return" a value, but not the variable itself. Hence it's address can not be retrieved. In other words ++i
is not an lvalue. Neither is i++
.
C++ is may be different from C in regard of certain constructs being l- and r-values.
http://eli.thegreenplace.net/2011/12/15/understanding-lvalues-and-rvalues-in-c-and-c/
For C++ these two are lvalues.
This simple code:
#include <stdio.h>
int main() {
int i=0;
++i = 10;
printf("\n%d\n", i);
++i = ++i;
printf("%d\n", i);
}
Compiled with gcc will give:
lvalue.c:3: error: invalid lvalue in assignment
lvalue.c:4: warning: incompatible implicit declaration of built-in function ‘printf’
lvalue.c:5: error: invalid lvalue in assignment
and for g++ compiles correctly and yelds:
10
12
Upvotes: 2
Reputation: 20392
Neither ++i
nor i++
are lvalues.
You might be thinking about *x++
and *++x
which are both lvalues (if x has a pointer type).
Upvotes: 4
Reputation: 13541
By making ++i
an lvalue, imagine that you can now do:
int i=2;
++i = ++i;
Apart from nasal daemons, what would you like i
to look like afterwards? 4? 3?
Upvotes: 0