cwinapigcc

Why is the compiler throwing this warning: "missing initializer"? Isn't the structure initialized?


I'm creating some sort of frontend for a program. To launch the program I'm using the call CreateProcess(), which among other things receives a pointer to a STARTUPINFO structure. To initialize the structure I used to do:

STARTUPINFO startupInfo = {0}; // Or even '\0'.
startupInfo.cb = sizeof(startupInfo);

When compiling the program with GCC enabling these sets of warnings -Wall -Wextra it gives me a warning saying that there's a missing initializer pointing to the first line.

warning: missing initializer
warning: (near initialization for 'startupInfo.lpReserved')

So I ended up doing:

STARTUPINFO startupInfo;
memset(&startupInfo, 0, sizeof(startupInfo));
startupInfo.cb = sizeof(startupInfo);

And this way the compiler doesn't give any warning. The question is, what is the difference between these ways of initializing a structure? Using the first method, isn't the structure initialized? Which one would you recommend?


Solution

  • GCC is just being overly paranoid - for no good reason in my opinion, but then it's certainly true that the GCC maintainers know a lot more about the nuances of C that I do.

    See this small thread of discussion about the problem on the GCC mailing list:

    The bottom line though - initializing the struct with just {0} will in fact zero initialize the whole thing.

    The C99 standard says the following in 6.7.8/21 "Initialization - Semantics":

    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.

    C90 says essentially the same in 6.5.7 with a bit different wording (in other words, C99 didn't add something new here).

    Also note that in C++ this was extended so that an empty set of braces, "{}", would perform value initialization on an object because there were situations (like templates) when you wouldn't even know what the members or how many members a type might have. So not only is it good practice, but necessary at times to have an initializer list that's shorter than the number of members an object might have.