Why is it so that a struct can be assigned after defining it using a compound literal (case b) in sample code), while an array cannot (case c))?
I understand that case a) does not work as at that point compiler has no clue of the memory layout on the rhs of the assignment. It could be a cast from any type. But going with this line, in my mind case c) is a perfectly well-defined situation.
typedef struct MyStruct {
int a, b, c;
} MyStruct_t;
void function(void) {
MyStruct_t st;
int arr[3];
// a) Invalid
st = {.a=1, .b=2, .c=3};
// b) Valid since C90
st = (MyStruct_t){.a=1, .b=2, .c=3};
// c) Invalid
arr = (int[3]){[0]=1, [1]=2, [2]=3};
}
Edit: I am aware that I cannot assign to an array - it's how C's been designed. I could use memcpy or just assign values individually.
After reading the comments and answers below, I guess now my question breaks down to the forever-debated conundrum of why you can't assign to arrays.
What's even more puzzling as suggested by this post and M.M's comment below is that the following assignments are perfectly valid (sure, it breaks strict aliasing rules). You can just wrap an array in a struct and do some nasty casting to mimic an assignable array.
typedef struct Arr3 {
int a[3];
} Arr3_t;
void function(void) {
Arr3_t a;
int arr[3];
a = (Arr3_t){{1, 2, 3}};
*(Arr3_t*)arr = a;
*(Arr3_t*)arr = (Arr3_t){{4, 5, 6}};
}
So then what's stopping developers to include a feature like this to, say C22(?)
C does not have assignment of arrays, at all. That is, where array has any array type, array = /* something here */ is invalid regardless of the contents of "something here". Whether it's a compound literal (which you seem to have confused with designated initializer, a completely different concept) is irrelevant. array1 = array2 would be just as invalid.
As to why it's invalid, at some level that's a question of the motivations/rationale of the C language and its design and unanswerable. However, mechanically, arrays in any context except the operand of sizeof or the operand of & "decay" to pointers to their first element. So in the case of:
arr = (int[3]){[0]=1, [1]=2, [2]=3};
you are attempting to assign pointer to the first element of the compound literal array to a non-lvalue (the rvalue produced when arr decays). And of course that is nonsense.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With