Read Arrays are pointers?. This explains the exception for this case. Change the value of a array statically declared would violate the definition of array.
All other cases you have a direct address, so the variable (which is a lvalue) contains a value. You can take any value and assign it to something that already has a value (usually as long as it has compatibility between them, but this compatibility is flexible).
As you’ve probably seen, a array ends up being a pointer to the real value. So if you assign a value to it, it is assigning to the pointer (currently pointing to the first element of the array) or for the real value? It is for the pointer, which by the definition of the language is not a lvalue. See the specification:
Except when it is the operand of the sizeof Operator, the _Alignof Operator, or the unary & Operator, or is a literal string 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.
A pure pointer would not be statically allocated, but in declaring you said that there would be something static. This is not compatible, the language cannot accept.
And you couldn’t even dream of copying the value of one array in another because nothing guarantees that one object would be compatible with another, and will allow to fade the memory or leave dirt, so much so that all copies of array need to be done manually or through ready-made functions such as memcpy()
or equivalent, if such a copy is possible (may not be in a protected writing area).
So if arrays do not decay to pointers the assignment you wanted to do could occur normally, because it would only be a sequence of bytes with known size, just as is the struct
(has exception) or other scalar types, not counting indirect, and therefore it would be a lvalue. The fact that it is the object directly allows the compiler to know what it is assigning.
That’s not a feature of array in itself, but from the memory address, see that the specification shows this, and we can exemplify with something that is also not valid:
int x = 1;
int *y = malloc(sizeof int);
&x = y;
I put in the Github for future reference.
What are you doing there? Are you saying that x
which is a name for a memory address (you’ve read about it on link above) and that the integer value has been placed 1
. Then you’re saying that this variable should point to another place in memory which is what’s set in y
. You’re not changing the value of the object, but you’re changing the variable. You do not want and cannot do this, the variable was not declared to be modified by code.
The only reason that the array statically declared is prevented from doing what you proposed is that it does exactly this operation, even if you don’t see it because of automatic decay. It only "appears" to be modifiable but is not.
You are trying to change the natural pointer of the variable that was not explicitly declared to be a pointer.
If statically declared arrays were lvalues there would be two scenarios for implementation: 1) when the array was copied, the program would copy only the memory address - in the same way as pointers - the problem here is that the array would lose its static quality and should be dynamically allocated - in the same way as pointers. Imagine, for example, the case of an array declared within a struct. How struct could reserve memory for this array, if it could be modified at runtime?
– Vander Santos
In the second case, the entire array would be copied - in this scenario, they would be more like structs - but here the implementation difficulties only increase. For how to copy arrays of different sizes? Worse than that, as C doesn’t even know the size of the array at runtime, the program can’t even know which size of the memory block has to be copied. And this difficulty is so absurd that even the implementation of string copy functions is complicated, given the amount of variations of
strcpy
existing, none of them very practical or good.– Vander Santos
And why doesn’t that happen with structs? Simple because structs have a well-known fixed length at compile and run time. So they’re as easy to copy as the primitive types.
– Vander Santos