Given that this is legal
uint8_t bytes[4] = { 1, 2, 3, 4 };
And this is not:
uint8_t bytes2[4];
bytes2 = { 1, 2, 3, 4 };
what does { 1, 2, 3, 4 }
represent?
Am assuming it's neither an rvalue or an lvalue. A preprocessor code candy that expands to something?
A syntax like {1,2,3,4};
is called brace-enclosed initializer list, it's an initializer. It can be only used for initialization (for array type).
Quoting C11
, chapter §6.7.9
The initializer for a scalar shall be a single expression,
[an array is not a scalar type, so not applicable for us]
An array of character type may be initialized by a character string literal or UTF−8 string literal, optionally enclosed in braces.
[We are not using a string literal here, so also not applicable for us]
Otherwise, the initializer for an object that has aggregate or union type shall be a brace-enclosed list of initializers for the elements or named members.
[This is the case of our interest]
and, P17,
Each brace-enclosed initializer list has an associated current object. When no designations are present, subobjects of the current object are initialized in order according to the type of the current object: array elements in increasing subscript order, structure members in declaration order, and the first named member of a union.[....]
So, here, the values from the brace enclosed list are not directly "assigned" to the array, they are used to initialize individual members of the array.
OTOH, an array type, is not a modifiable lvalue, so it cannot be assigned. In other words, an array variable cannot be used as the LHS of the assignment operator.
To elaborate, from C11
, chapter §6.5.16
assignment operator shall have a modifiable lvalue as its left operand.
{1,2,3,4}
is an initializer-list, a particular syntax token that can only be used on the line where the array is declared.
This is regulated purely by the C standard syntax. There's no particular rationale behind it, this is just how the language is defined. In the C syntax, arrays cannot be assigned to, nor copied by assignment.
You can however dodge the syntax restrictions in several ways, to overwrite all values at once. The simplest way is just to create a temporary array and memcpy:
uint8_t tmp[] = {5,6,7,8};
memcpy(bytes, tmp, sizeof bytes);
Alternatively, use a compound literal:
memcpy(bytes, (uint8_t[]){5,6,7,8}, sizeof bytes);
If it makes sense for the specific application, you can also wrap the array in a struct to bypass the syntax restrictions:
typedef struct
{
uint8_t data [4];
} array_t;
...
array_t bytes = { .data = {1,2,3,4} };
array_t tmp = { .data = {5,6,7,8} };
bytes = tmp; // works just fine, structs can be copied this way
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