views:

222

answers:

2

I have a set of structs, defined as follows:

typedef struct
{
    int index;
    int array[10];
}
Item;

typedef struct
{
    Item A;
    Item B;
    Item C;
}
Collection;

And I want to declare a variable of type Collection as follows:

Collection collection =
{
    { 1, 0 },  /* item A */
    { 2, 0 },  /* item B */
    { 3, 0 }   /* item C */
};

Will this set the three index variables to 1, 2, and 3, while at the same time initializing all three array[] variables with zero?

It appears to be working on my compiler, but I would like to know if this is the standard behaviour.

+4  A: 

This is standards compliant. See the section -- 6.7.8 Initialization. Further, you can use designated initializers in C99 conforming compilers.

dirkgently
That's pretty cool. I had never heard of designated initializers until today!
e.James
+6  A: 

There should be additional braces around the zeros to make them valid array initializers:

Collection collection =
{
    { 1, {0} },  /* item A */
    { 2, {0} },  /* item B */
    { 3, {0} }   /* item C */
};

Apart from that it will correctly initialize the structure.

The inizializer is also valid without the additional braces, but you will get compiler warnings and it's much less confusing if initializers for subaggregates are made explicit. For the details see section 6.7.8 in the C99 standard that dirkgently refers to in his answer, especially 6.7.8 (20) and the examples in 6.7.8 (29).

sth
Absolutely valid observation, although it hardly answers the question. +1 anyway
qrdl
+1. I think even without the braces we have what is known as "an incompletely but consistently bracketed initialization".
dirkgently
@qrdl: I read the question as "is this way of doing it correct", but you're right, I added another line making it clear that it will initialize the structure correctly.
sth
+1 for answering my next question before I had to ask it ;)
e.James
Or get rid of the extra 0s entirely: `Collection collection = { { 1 }, { 2 }, { 3 } };`.
jamesdlin