struct mystruct s[10] = {{0}};
This appears to initialize an array of structs to 0. How does the nested braces syntax work?
struct mystruct s[10] = {{0}};
This appears to initialize an array of structs to 0. How does the nested braces syntax work?
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.
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.
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.
It's useful to note that while the inner braces are optional, the compiler will check to ensure that opening braces only appear where they ought, and that no nested item has too many initializers. Further, one may leave out some fields of a structure and have the compiler automatically zero them, even if the structure is not at the end of the array. Note that implementations vary in their efficiency of handling this; some will divide the initialization record into small pieces, while others will simply insert lots of zeroes in the code. For example, if each struct looked like:
typedef struct { char name[8]; char more_stuff[1016]; } THINGIE; THINGIE my_array = {{"Fred"},{"George"},{"Mark"}};
some compilers would generate 3K worth of const data, while others would generate three relatively-small 'const-init' records.