Categories
c c89 gcc initialization misra

How standard is the {0} initializer in C89?

In my current project, which uses the MISRA 2004 standard, we use three GCC compilers, versions 3.2.3, 4.4.2 and 5.4.0.

We run build checks with the pedantic switch and c89 standard and a load of other restrictions. One of the restrictions is that all data must be initialised at declaration.

I have a problem in that on GCC 3.2.3, the universal zero initialiser {0} only compiles for arrays of the basic unitary types. If I have an array of structs, then I get a missing braces warning and the warning only goes away if I change {0} for {{0}}.

struct my_type my_thing[NUMBER_OF_THINGS] = {0};

becomes

struct my_type my_thing[NUMBER_OF_THINGS] = {{0}};

This does not work, however, for arrays of structs which have struct members. Then the problem is with the 4.4.2 compiler, which gives missing initialiser errors, so I had to do this:

struct my_struct_with_structs_inside my_other_thing[NUMBER_OF_THINGS] = {{0, 0, {0}, 0}};

This satisfies the compilers, but it trips our MISRA checker, because MISRA demands either the universal single {0} initialiser or the full, whole-array initialiser:

struct my_struct_with_structs_inside my_other_thing[NUMBER_OF_THINGS] = {{0, 0, {0}, 0},
{0, 0, {0}, 0},
{0, 0, {0}, 0},
{0, 0, {0}, 0},
{0, 0, {0}, 0}};

This is impractical for us because we have all sorts of restrictions and NUMBER_OF_THINGS may be changeable and be automatically generated from outside the source code at build time.

Nub and Crux

I would like to be able to say to my boss that the so-called universal initialiser {0} is sufficient for initialising any array. I have found threads on the GCC mailing lists and Bugzilla, going back many years, which consider the compiler warnings I’ve mentioned to be bugs, and stating that {0} is part of the standard. However, none of them mention which standard, and I have been unable to find {0} in the ISO C89 or C99 drafts, or K&R v2. Is the {0} a standard? Is there any way to guarantee that an array of structs with struct members is initialised to all zeros (or NULL)?

The trouble is that, while I can magic away the violations of the MISRA code, I am unsure that doing this:

struct my_struct_with_structs_inside my_other_thing[NUMBER_OF_THINGS] = {{0, 0, {0}, 0}};

…is sufficient to guarantee that the array will be completely zeroed.

Can anyone please offer wisdom from the root of this problem?