4
#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?

msc
  • 33,420
  • 29
  • 119
  • 214
Geeta
  • 91
  • 1

5 Answers5

11

*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.

alk
  • 69,737
  • 10
  • 105
  • 255
3

*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.
gsamaras
  • 71,951
  • 46
  • 188
  • 305
3

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.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
2

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.

haccks
  • 104,019
  • 25
  • 176
  • 264
1

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]
Naman
  • 27,789
  • 26
  • 218
  • 353