Referring to the standard project C11 N1570 :
Section 6.5.2.5p4:
In any case, the result is an lvalue.
An "lvalue" is, roughly speaking, an expression that denotes an object, but it is important to note that not all lvalues โโare modifiable. A simple example:
const int x = 42;
The name x is an lvalue, but it is not a mutable value of an lvalue. (Array type expressions cannot be modifiable lvalues โโbecause you cannot assign an array object, but array elements can be modifiable.)
Point 5 of the same section:
Compound literal value - This is the name of an unnamed object that is initialized with a list of initializers. If a composite literal is outside the function body, the object has a static storage duration; otherwise, it has an automatic storage duration associated with the closing unit.
The section describing compound literals does not specifically state whether an unnamed object is modifiable or not. In the absence of such a statement, an object is considered modifiable if the type is const -qualified.
Example in question:
((int []) {1,2,3})[0] = 100;
not particularly useful as there is no way to refer to an unnamed object after assignment. But a similar design can be very useful. A contrived example:
#include <stdio.h> int main(void) { int *ptr = (int[]){1, 2, 3}; ptr[0] = 100; printf("%d %d %d\n", ptr[0], ptr[1], ptr[2]); }
As mentioned above, an array has an automatic storage duration, which means that if it is created inside a function, it will cease to exist when the function returns. Component literals do not replace malloc .