Reputation: 1048
Having trouble understanding, How following statement would be evaluated :
++*++ptr and *ptr++++
As per my understanding first would give me lValue required because after * is applied it would give value which cannot be used for ++ operator. But, the result is opposite. Please explain.
Second statement gives me error : batch3.c:6:21: error: lvalue required as increment operand printf("%d", *ptr++++);
Upvotes: 2
Views: 739
Reputation: 123578
First, some standardese:
6.5.2.4 Postfix increment and decrement operators
Constraints
1 The operand of the postfix increment or decrement operator shall have atomic, qualified, or unqualified real or pointer type, and shall be a modifiable lvalue.
Semantics
2 The result of the postfix++
operator is the value of the operand. As a side effect, the value of the operand object is incremented (that is, the value 1 of the appropriate type is added to it). See the discussions of additive operators and compound assignment for information on constraints, types, and conversions and the effects of operations on pointers. The value computation of the result is sequenced before the side effect of updating the stored value of the operand. With respect to an indeterminately-sequenced function call, the operation of postfix++
is a single evaluation. Postfix++
on an object with atomic type is a read-modify-write operation withmemory_order_seq_cst
memory order semantics.98)
...
6.5.16 Assignment operators
...
3 An assignment operator stores a value in the object designated by the left operand. An assignment expression has the value of the left operand after the assignment,111) but is not an lvalue. The type of an assignment expression is the type the left operand would have after lvalue conversion. The side effect of updating the stored value of the left operand is sequenced after the value computations of the left and right operands. The evaluations of the operands are unsequenced.
Emphasis mine.
The upshot of that wall of text is that the results of the expressions ptr++
and ++ptr
are not lvalues. However, both expressions result in pointer values, so they may be the operands of the unary *
operator, and the results of *ptr++
and *++ptr
may be lvalues.
This is why ++*++ptr
works; you're incrementing the result of *++ptr
, which may be an lvalue. However, *ptr++++
is parsed as *(((ptr)++)++)
(postfix ++
has higher precedence than unary *
); the result of ptr++
is the operand to the second ++
, but since the result of ptr++
is not an lvalue, the compiler complains. If you had written it as (*ptr++)++
, then the expression would be valid.
In short:
++*++ptr - valid, equivalent to ++(*ptr++)
*++++ptr - invalid, equivalent to *(++(++ptr)), result of ++ptr is not an lvalue
++++*ptr - invalid, equivalent to ++(++(*ptr)), result of ++*ptr is not an lvalue
*ptr++++ - invalid, equivalent to *((ptr++)++), result pf ptr++ is not an lvalue
(*ptr)++++ - invalid, equivalent to ((*ptr)++)++, result of (*ptr)++ is not an lvalue
(*ptr++)++ - valid
Upvotes: 2
Reputation: 37954
Considering that these two expressions are separate (note that and
is defined <iso646.h>
) here what happens:
First one ++*++ptr
is equivalent to ++(*(++ptr))
, as both prefix ++
and unary *
have the same precedence and assiociativity is from right to left for both of them. See following example as an illustration:
#include <stdio.h>
int main(void)
{
int a[] = {1, 2};
int *ptr = a;
++(*(++ptr));
printf("%d\n", a[0]);
printf("%d\n", a[1]);
return 0;
}
Result:
1
3
The latter expression is not compilable, as ptr++
subexpression is not a modifiable lvalue. Note that postix ++
has higher precedence, that *
(indirection operator) and its associativity is from left to right.
Upvotes: 1
Reputation: 19874
++
operator has higher precedence over *
So the pointer will be incremented first and then dereferenced.
*p++
First
p++
Then *p++
For ++
there has to be a value which needs to be incremented. But the below expression doesn't provide the lvalue for the ++
. p++
is not a modifiable lvalue.
*ptr++++;
Upvotes: 1