C: How does nested braces for array of struct initialization work?

Solution 1:

Any fields not specified are initialized to zero. So here you have an array of structs. You're initializing the first element of the array with a structure initializer that initializes the first element of the structure to zero. The rest of the first structure and the rest of the array elements will all be zero too. It's a nice idiom.

Solution 2:

As shown?

Basically, you should enclose each compound type - array, structure, etc - inside its own level of braces.

Consider:

struct mystruct
{
    int i;
    double d;
    char   s[10];
    int    a[5];
} s[10] =
{
      { 0, 0.0, "abc", { 1, 2, 3, 4, 5 } },
      { 1, 1.0, "def", { 2, 3          } }, // Partially initialized array
      { 2, 2.0, { 'x', 'y', 'z' }, { 0 } }, // Strings are a shorthand
[9] = { 9, 99,  0,     { 9, 8, 7, 6, 5 } }, // C99 - initialize row 9
};

But you can also omit braces if you insist (bad, archaic practice):

struct mystruct t[3] =
{ // You cannot avoid using these outside braces
  0, 0.00, "abc", 1, 2, 3, 4, 5,  // Omitted braces
  1, 1.11, "bcd", 2, 3, 4, 5, 4,
  2, 2.34,                        // Omitted values
};

Any omitted initializers are treated as zeroes.

Solution 3:

It is not the nested braces that initializes. The outer braces are indicating that an array is being initialized:

struct mystruct s[10] = {           };

Since this is an array of structures, each structures can be initialized with further braces:

struct mystruct { int x, y, z};

struct mystruct s[10] = { {0, 1, 2}, // <-- initializes s[0].x, s[0].y, s[0].z
                          {1, 2, 3}, // <-- initializes s[1].x, s[1].y, s[1].z
                          {2, 3, 4}  // <-- initializes s[2].x, s[2].y, s[2].z
};

Notice that only first three elements are initialized. According to C standard the rest 7 elements must be initialized to 0. This is what happens to your code too. As xscott mentioned in his reply, everything omitted in initializer list is initialized to 0.