tags:

views:

117

answers:

4
struct mystruct s[10] = {{0}};

This appears to initialize an array of structs to 0. How does the nested braces syntax work?

+7  A: 

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.

xscott
Just to make sure I'm understanding this correctly. Since all non-specified fields are initialized to zero, the `= {{0}}` essentially has no effect?
jay.lee
It does have an effect. It specifically initializes the first element to zero, and then implicitly initializes the rest of the elements to zero. If you omitted the {{0}}, you would get random garbage if you declared it inside of a function (on the stack). (Note that if you declare this as a global and omit the {{0}}, it will also be initialized to zero, but for different reasons.)
xscott
+2  A: 

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.

Donotalo
+2  A: 

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.

Jonathan Leffler
On advantage of using the braces is that it lets you omit the initialization of parts of some members (which will then implicitly be initialized to zero) while continuing to initialize later members. Your use of `{ 'x', 'y', 'z' },` is an example of this.
R..
A: 

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.

supercat
The compiler cannot check that opening braces only appear where they "ought" to, because they're valid anywhere. Even this is valid C: `int x = {0};`.
R..
You left out the "typedef" keyword before your struct definition. In your code above, THINGIE is a variable, not a type.
xscott
@R: True; where you get validation is if you try to put two or more things in a brace. I'm pretty sure "int x = {0,1};" is not legal.
supercat