Stephane
Stephane

Reputation: 153

Array of struct initialization in C

I cannot find the solution to this. I can initialize an array of struct like this:

typedef struct S_A {
    int x;
} T_A;

T_A ta1[3];

ta1[0] = (T_A){0};
ta1[1] = (T_A){1};
ta1[2] = (T_A){2};

T_A ta2[3] = { {0}, {1}, {2} };

But how can I do a one-line initialization after declaration?

T_A ta3[3];

ta3 = (?){ {?}, {?}, {?} };

ta3 = (T_A[3]){ { 0 }, { 1 }, { 2 } }; // error
ta3 = (T_A*)  { { 0 }, { 1 }, { 2 } }; // error

Upvotes: 1

Views: 253

Answers (3)

klutt
klutt

Reputation: 31296

In C, an initialization is something that you do simultaneously as the declaration. You cannot do it afterwards.

This can be seen in the grammar that you can find here: https://www.lysator.liu.se/c/ANSI-C-grammar-y.html

Whenever you use the = after you have finished the declaration, it's an assignment and not an initialization, and assignments have different rules. One of these rules is that the common way of initializing arrays - = {1,2,3} - simply is not allowed. You have to use memcpy or something like that.

When it comes to nonarrays, like int, double etc and their pointers, it is still true that you cannot formally initialize them after declaration, but for those, assignment has the same syntax so it can be confusing.

However, there is a trick that can be used for arrays. Wrap the array in a struct and do like this:

struct wrapper{
    int arr[3];
} x;

x = (struct wrapper){{1,2,3}};

Upvotes: 5

Alex Lop.
Alex Lop.

Reputation: 6875

Unfortunately, as others already mentioned, one cannot assign anything to an array.

int arr[N];
...
arr = ... ; // --> This will always fail compilation

The only option is such case is either to assign new value to each array entry separately

arr[i] = ...;

Or use memcpy to copy values from other memory location.

The interesting thing is that if one defines a struct of array(s) rather than an array of struct(s):

typedef struct S_S {
    int x[3];
} T_S;

then the assignment after the declaration is allowed:

typedef struct S_S {
     int x[3];
} T_S;

int main(void)
{
   T_S y;

   y = (T_S){.x = {1, 2, 3}}; //OK!

  return 0;
}

This perfectly compiles (assuming your compiler supports C99 standard)!

Upvotes: 1

KamilCuk
KamilCuk

Reputation: 140880

Arrays are special in C. You can only once initialize arrays. You can't then "re-initialize" arrays. Assignments on arrays don't work. Array is in most contexts a pointer that you can't assign to. You can't:

int arr[3];
// arr = {1,2,3}; // will not work
// arr = anything; // will not work

You only can memcpy to them with a compound literal:

memcpy(ta3, (T_A[3]){ { 0 }, { 1 }, { 2 } }, sizeof(ta3));

Or without compund literal initialize a temporary variable and memcpy:

const T_A temp[3] = { { 0 }, { 1 }, { 2 } };
memcpy(ta3, temp, sizeof(ta3));

Upvotes: 9

Related Questions