Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a reason why an array name is not an lvalue?

Tags:

arrays

c

lvalue

For example,

int x[10];
int i = 0;
x = &i; //error occurs!

According to C - A Reference Manual, an array name cannot be an lvalue. Thus, x cannot be an lvalue. But, what is the reason the array name cannot be an lvalue? For example, why does an error occur in the third line?

like image 200
Jin Avatar asked Aug 18 '16 15:08

Jin


People also ask

Is array lvalue or rvalue?

An array is an unmodifiable lvalue, not an rvalue.

Is pointer an lvalue in C++?

in the second line of your program, the expression &i is an expression of type int* , and is thusly an example of a pointer being treated as an rvalue. You're asking taking the result of the expression &i and using it as the rvalue to the assignment operator, with int *p as the lvalue of said operator.


2 Answers

Your reference is incorrect. An array can be an lvalue (but not a modifiable lvalue), and an "array name" (identifier) is always an lvalue.

Take your example:

int x[10];
int i = 0;
x = &i; //error occurs!

Apply C11 6.5.1, paragraph 2:

An identifier is a primary expression, provided it has been declared as designating an object (in which case it is an lvalue) ...

We see that x is a primary expression and is an lvalue, because it has previously been declared as designating an array object.

However, the C language rules state that an array expression in various contexts, including the left-hand-side of an assignment expression, are converted to a pointer which points at the first element of the array and is not an lvalue, even if the array was. Specifically:

Except when it is the operand of the sizeof operator, the _Alignof 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. If the array object has register storage class, the behavior is undefined.

(C11 6.3.2.1 paragraph 3).

The pointer which is the result of the conversion specified above is not an lvalue because an lvalue designates an object, and there is no suitable object holding the pointer value; the array object holds the elements of the array, not a pointer to those elements.

The example you use in your question implies that you understand that an array expression decays (is converted to) a pointer value, but I think you are failing to recognize that after the conversion, the pointer value and the array are two different things. The pointer is not an lvalue; the array might be (and in your example, it is). Whether or not arrays are lvalues in fact has no bearing on your example; it is the pointer value that you are trying to assign to.

If you were to ask instead: Why do arrays decay to pointers when they are on the left-hand-side of an assignment operator? - then I suspect that there is no particularly good answer. C just doesn't allow assignment to arrays, historically.

like image 107
davmac Avatar answered Nov 15 '22 20:11

davmac


Array names are non-modifiable lvalues in C.:)

Arrays are named extents of memory where their elements are placed. So you may not substitute one extent of memory for another extent of memory. Each extent of memory initially allocated for an array declaration has its own unique name. Each array name is bounded with its own extent of memory.

like image 44
Vlad from Moscow Avatar answered Nov 15 '22 21:11

Vlad from Moscow