Why ++(*p) is not giving l-value required error?

247 Views Asked by At
#include <stdio.h>
int main()
{
    int arr[] = {1, 2, 3, 4, 5};
    int *p = arr;
    ++*p;
    p += 2;
    printf("%d", *p);
    return 0;
}

Why is this code not giving any compile time error,My doubt is ++*p is evaluated as ++(*p) and *p will be constant value 1 ,when we do ++(1) which is not a l-value,why is compiler not giving an error?

5

There are 5 best solutions below

0
haccks On

Why ++(*p) is not giving l-value required error?

Dereference operator on a pointer yields a lvalue. Therefore, *p is a lvalue and using pre-increment operator on it is valid.

0
alk On

*p will be constant value [...]

No, it is the same as arr[0].

So

++(*p);

is the same as

++(p[0]);

is the same as

++(arr[0]);

which is a perfectly valid statement.

0
gsamaras On

*p will be constant value

No, it won't. *p is a[0] when you do int *p = arr;. a[0] is not a constant value, and since they are the same, *p is not a constant value either.

As a result, this:

++(*p);

is equivalent to:

++(a[0]);

which increments the element at the first position of the array, as you can see clearly.

But looking back at ++(*p), one can see that:

  • *p dereferences the pointer, resulting in an l-value.
  • Then we have (*p), the l-value in parentheses.
  • ++(*p) applies the pre-increment operator to an l-value, which is value, thus no compiler error should be generated.
5
Naman On

Just note both the statements used by you :

++*p; // increments the value pointed by *p at that time `a[0]` by 1
p += 2; // increments the address p is storing by 2

And the reason there is no l-value required error is because in your statement :

++*p; // *p is not a constant, it is same as a[0]
1
John Bollinger On

Object pointer dereferencing does not itself produce the value to which the pointer points. Instead it produces an lvalue that refers to that value. In the words of the standard:

The unary * operator denotes indirection. If the operand points to a function, the result is a function designator; if it points to an object, the result is an lvalue designating the object. If the operand has type "pointer to type", the result has type "type".

(C2011, 6.5.3.2/4; emphasis added)

Unary * is thus among a class of operators that can be considered to operate on the identity of an object, as opposed to on its value. The & operator and and some uses of the sizeof operator can also be considered to be in this category.