1

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
3
  • ok second time i have this problem, why my "hello/hi" disappear at the beginning of my posts ? is it normal ? do i do something wrong ? Commented Sep 10, 2019 at 21:27
  • 1
    Regarding greetings: see here (especially the second answer) Commented Sep 10, 2019 at 21:33
  • 4
    You cannot initialize after the declaration. At that point you will be dealing in assignment. You cannot assign an array. Commented Sep 10, 2019 at 21:33

3 Answers 3

9

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));
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, that's crystal clear ! Since i could do it with structs i thought it was possible to do so with arrays of structs also, but no ^^. Thanks a lot.
@Stephane There is an old hack where you wrap an array in a struct declaration typedef struct { int arr[5] } structarray; just so that you can assign one structarray to another. It makes everything else a bit clunky, though, so think about the trade-offs before you dive in.
5

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}};

2 Comments

thanks for the clarification ! But no thanks for the link XD, i am not reading that, i'd rather brute force my way until it compile hahaha. No more seriously, Yacc, bnf, and other grammar documents like those are just unreadable for me. if I have to do a compiler one day i'll do, but till then...
@Stephane There is no need to learn it completely, but I do recommend at least taking a quick look. I especially recommend learning the difference between statement and primary expression. Also, understanding the grammar can make it A LOT easier to decode the cryptic warnings and errors the compiler yields.
1

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)!

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.