views:

219

answers:

4
int val = 5;

printf("%d",++val++); //gives compilation error : '++' needs l-value

int *p = &val;
printf("%d",++*p++); //no error

Could someone explain these 2 cases? Thanks.

+18  A: 

++val++ is the same as ++(val++). Since the result of val++ is not an lvalue, this is illegal. And as Stephen Canon pointed out, if the result of val++ were an lvalue, ++(val++) would be undefined behavior as there is no sequence point between the ++s.

++*p++ is the same as ++(*(p++)). Since the result of *(p++) is an lvalue, this is legal.

sepp2k
Excellent answer, though I would note that that even if `val++` were an lvalue, the behavior would still be undefined. `(++val)++` in C++, for example, would invoke undefined behavior.
Stephen Canon
@Stephen: Very good point, I'll add that to the answer.
sepp2k
Post-increment operator always returns an `rvalue`(in C as well as in C++). In C++, `(++val)++` invokes Undefined Behavior because pre-increment(`++`) operator returns an lvalue(in C++) and the value of `val` is being modified more than once between two sequence points.
Prasoon Saurav
+4  A: 

int j = ++val++; //gives compilation error

That because you cannot pre-increment an rvalue. ++val++ is interpreted as ++(val++) because post-increment operator has higher precedence than pre-increment operator. val++ returns an rvalue and pre-increment operator requires its operand to be an lvalue. :)

int k = ++*p++; //no error

++*p++ is interpreted as ++(*(p++)), which is perfectly valid.

Prasoon Saurav
+3  A: 

The expression ++val++ is the same as (++val)++ (or perhaps ++(val++), anyway it's not very relevant). The result of the ++ operator is not the variable, but the value, and you can't apply the operator to a value.

The expression ++*p++ is the same as ++(*(p++)). The result of p++ is the value, but the result of *(p++) is a memory location, which the ++ operator can be applied to.

Guffa
`++val++` is the same as `++(val++)`, which is **not** the same as `(++val)++`. (Though in C, both are syntactically invalid)
Stephen Canon
@Stephen Canon: Yes, it's just not obvious which one it evaluates to. As the expression is invalid I never bothered to learn which of two invalid variants it is. :)
Guffa
@Guffa: ah, but in C++, one of them is invalid while the other is syntactically valid but semantically undefined. (C++ is wacky!)
Stephen Canon
+1  A: 

Hi,

also note that you're changing the address of the pointer by

int k = ++*p++;
sled
@sled: yes I know that. I used it for simplicity. Instead of int val, I could have used int array.
understack