2

Why can't I do p=numbers++ or p=++numbers? The compiler shows the message: "lvalue required as increment operand" but isn't the pointer p a left value?

int main(int argc, char *argv[]){
    int numbers[] = {1,2,3,4,5,6}, *p;
    p=numbers++;
    printf("%d ",*p);
    return 0;
}
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
Roni Castro
  • 1,968
  • 21
  • 40

4 Answers4

2

When you declare and define an array, the name of the array is an expression that evaluates to the address of the first element of the array. Think of the name as a constant that holds the address of the first element.

Once memory has been allocated for the array, the address of the array cannot be changed. Consequently, the value of the array identifier (name) cannot be changed either.

In your code, when you have

p = numbers++;

you are asking that numbers, which has the constant value of the address of the first element of the array, be incremented and point to the second element instead. This is not a legal operation. The increment operand requires a modifiable lvalue, and the name of the array is not a modifiable lvalue.

What is an lvalue? It is a locator value: something that identifies an area of memory that can hold another value. So when you declare:

int a = 5;

a signifies an area of memory large enough to hold an int, and the int held in that area of memory is 5. You can change that int by assignment:

a = 7;

but the identifier a still signifies the same area of memory. This means a is a modifiable lvalue.

When you declare and define your array:

int numbers[] = { 1, 2, 3, 4, 5, 6 };

numbers is an lvalue, in that it specifies an area of memory that holds the array of specified integers, but it is not modifiable. You can change the value of the elements in numbers, but you cannot change the value of numbers itself. numbers always evaluates to &numbers[0].

If you want to change where p points so that it points to the second element instead of the first, use:

p = numbers + 1;

This does not change the value of numbers itself, only that of p. numbers is still &numbers[0] and p will be &numbers[1].

Hope this is clear!

verbose
  • 7,827
  • 1
  • 25
  • 40
1

numbers++ is the equivalent of numbers = numbers + 1

However, numbers here is an array and you cannot modify the address of an array.

lvalue doesn't mean a "left value"

P0W
  • 46,614
  • 9
  • 72
  • 119
1

First I recommend that you read the C FAQ's section on Arrays and Pointers it is one of the better general references.

To directly address your error, if we look at the draft C99 standard we see that in sections 6.5.2.4 Postfix increment and decrement operators and 6.5.3.1 Prefix increment and decrement operators say in paragraph 1:

The operand of the prefix increment or decrement operator shall have qualified or unqualified real or pointer type and shall be a modifiable lvalue.

section 6.3.2.1 Lvalues, arrays, and function designators paragraph 3 says:

Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue. [...]

and paragraph 1 says:

[...] A modifiable lvalue is an lvalue that does not have array type, [...]

so even though an array will decay to a pointer to the first element in many circumstances it is not a lvalue.

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
0

numbers is NOT a pointer. It is an array with this definition int numbers[] = {1,2,3,4,5,6}, and a rvalue. So the compiler shows the message: "lvalue required as increment operand".

Difference between array and pointer. Pointers - Difference between Array and Pointer

Community
  • 1
  • 1
lulyon
  • 6,707
  • 7
  • 32
  • 49