Blank initialising an array of structs in C99

2019-09-14 22:37发布

问题:

This seems like a hole in my knowledge. As far as I am aware, in C99 if you initialise a single element of a struct and no others, the others are zero initialised. Does the following code zero initialise all the members of a struct though?

typedef struct
{
    int foo;
    int bar;
    char* foos;
    double dar;
} some_struct_t;

some_struct_t mystructs[100] = {};

Update: There are some comments indicating that this syntax is an extension. If that is the case, is there any way of doing this that is pure C99 compliant?

回答1:

As per C11, chapter §6.7.9, Initialization syntax, (for the sake of completeness, same mentioned in chapter §6.7.8 in C99)

initializer:

      assignment-expression
      { initializer-list }
      { initializer-list , }

initializer-list:
      designationopt initializer
      initializer-list , designationopt initializer

designation:
      designator-list =

designator-list:
      designator
      designator-list designator

designator:
      [ constant-expression ]
      . identifier

Which implies, the brace closed initializer list should have at minimum one initializer element (object).

In your code, the empty initializer list

 some_struct_t mystructs[100] = {};  //empty list

is not a valid pure C syntax; it's a compiler extension.

You need to mention a single element in the list to make it standard conforming, like

some_struct_t mystructs[100] = {0};

which meets the criteria, from paragraph 21 of same standard(s),

If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.

So, in this case, you have one explicit 0 and remaining implicit zero-initialization (or similar).



回答2:

Because it's array initialisation, you would need

some_struct_t mystructs[100] = { 0 }; // ensure all array elements (struct) being zero initialisation


回答3:

For structs/unions (and arrays) there is a rule saying that if it is partially initialized, the rest of the items that didn't get initialized explicitly by the programmer are set to zero.

So by typing some_struct_t mystructs[100] = {0}; you tell the compiler to explicitly set foo to zero. And then the rest of the struct members gets set to zero as well, implicitly.

This has nothing to do with C99, but works for all C standard versions. Although in C99/C11, a designated initializer {.foo=0} would have achieved the very same result.