Compiling this with -Wmissing-field-initializers evokes a warning: struct foo { int a; int b; }; struct foo f = { 1 }; but with "designated initializers" it does not: struct foo { int a; int b; }; struct foo f = { .a = 1 }; That -Wmissing-field-initializers works this way is even documented. My quandary is that I'd prefer to use the more readable and maintainable c99 form, especially with long lists of member names: foo = { .f1 = callback_a, .f2 = callback_b, .f3 = callback_c, ... .fn = callback_n, }; Then, it's obvious that foo.f23 is initialized to callback_23, whereas with old-style initializations, I'd have to count, and if ever I had the misfortune to reorder member names, and signatures are similar, it'd be easy to miss the error. However, the old-style initialization has the advantage that when I add a new member, gcc -Wmissing-field-initializers will prompt me to add a new initializer. With the c99-style, there seems to be no way to evoke a similar prod. Maybe we can get the best of both worlds? Paolo Bonzini mentioned that this would be easy to implement, and that -Wmissing-field-initializers=2 may be the way to do it, given the precedent of -Wstrict-overflow and -Wstrict-overflow=<N>.
I have the same (or similar) problem, and would like to have an option to enable warnings for incomplete structure initialization with designated initializers, where not all fields were explicitly assigned. (I know that the omitted fields are going to be 0, but that does not help me much in my embedded project. I would really like a compilation warning for the occasional misses, and not have to use other code analysis tools. Unfortunately splint does not even work for gnu99 code.) More details, examples can be found here: http://stackoverflow.com/questions/19430285/how-to-ensure-structures-are-completly-initialized-by-name-in-gcc Thanks in advance for anyone who can help us out.
(In reply to Szikra István from comment #1) > I have the same (or similar) problem, and would like to have an option to > enable warnings for incomplete structure initialization with designated > initializers, where not all fields were explicitly assigned. I don't think GCC devs would be against this in principle if someone provided a sensible patch: http://gcc.gnu.org/contribute.html The relevant code is at gcc/c/c-typeck.c: pop_init_level /* Warn when some struct elements are implicitly initialized to zero. */ if (warn_missing_field_initializers && constructor_type && TREE_CODE (constructor_type) == RECORD_TYPE && constructor_unfilled_fields) { bool constructor_zeroinit = (vec_safe_length (constructor_elements) == 1 && integer_zerop ((*constructor_elements)[0].value)); /* Do not warn for flexible array members or zero-length arrays. */ while (constructor_unfilled_fields && (!DECL_SIZE (constructor_unfilled_fields) || integer_zerop (DECL_SIZE (constructor_unfilled_fields)))) constructor_unfilled_fields = DECL_CHAIN (constructor_unfilled_fields); if (constructor_unfilled_fields /* Do not warn if this level of the initializer uses member designators; it is likely to be deliberate. */ && !constructor_designated /* Do not warn about initializing with ` = {0}'. */ && !constructor_zeroinit) { if (warning_at (input_location, OPT_Wmissing_field_initializers, "missing initializer for field %qD of %qT", constructor_unfilled_fields, constructor_type)) inform (DECL_SOURCE_LOCATION (constructor_unfilled_fields), "%qD declared here", constructor_unfilled_fields); } } Perhaps sinking the !constructor_designated check into the if, and adding an 'else'? Or simply deleting the check and doing: if (warning_at (input_location, !constructor_designated check ? OPT_Wmissing_field_initializers : OPT_Wmissing_field_initializers_2, where OPT_Wmissing_field_initializers_2 corresponds to a new option Wmissing-field-initializers=2 that needs to be added to c.opt (and documented in doc/invoke.texi).
Also, I would propose to call the warning -Wmissing-designated-initializers better than a number that does not mean much.
Confirmed.
GCC 6.1 has been released.
GCC 6.2 is being released, adjusting target milestone
GCC 6.3 is being released, adjusting target milestone.
If it helps implementing this legitimate distinction between use cases, i.e. default initialisation vs. software maintenance, I'd be happy having to attach a type attribute. For example, struct foo { int a; int b; } __attribute__((explicit_initialization)); Or any better name of an attribute. The attribute could tell the compiler to please use its knowledge of missing field initialisers, and, less paradoxically, to warn, actually, when -Wmissing-field-initializers is in effect. Just as it does when there are no designator in the initialiser list. For software maintenance this will be a boon. By analogy, I'd like to illustrate this use case like this: I don't want the compiler to be silent by force whenever it notices a missing implementation of a member function/Obj-C method/Ada prim op just because the programmer had given some other of these a name---assuming the respective language were to allow this at all.
I'm unsetting Target Milestone, because if this is changed it should be done on trunk not a release branch.
(In reply to Georg from comment #8) > If it helps implementing this legitimate distinction between > use cases, i.e. default initialisation vs. software maintenance, > I'd be happy having to attach a type attribute. For example, This seems more complicated than extending -Wm-f-i or adding a new option. I think the current behavior is historical and does not make sense nowadays. If the patch reviewers complain that the behavior of -Wm-f-i should not change, then just add a new option or a numeric level to -Wm-f-i, whatever reviewers prefer (see point 10 in https://gcc.gnu.org/wiki/Community). The reason this has not been implemented in 8 years is not any a priori rejection, but simply nobody has had the time or the motivation to submit a patch: https://gcc.gnu.org/wiki/GettingStarted#Basics:_Contributing_to_GCC_in_10_easy_steps
It seems this was actually implemented at some point (at least for C++, maybe that was the case all along already), though the manual page was not updated to reflect this. Taking the example from the manual (which is documented to *not* cause this warning): matthijs@grubby:~$ cat foo.cpp struct s { int f, g, h; }; struct s x = { .f = 3, .g = 4 }; matthijs@grubby:~$ gcc foo.cpp -c -Wall -Wextra foo.cpp:2:31: warning: missing initializer for member ‘s::h’ [-Wmissing-field-initializers] struct s x = { .f = 3, .g = 4 }; ^ However, this seems to be the case only for C++, if I rename to foo.c, no warning is emitted. I actually came here looking for a way to *disable* this warning for designated initializers on a specific struct. I was hoping to use a struct with designated initializers as an elegant way to specify configuration with optional fields (e.g. by lettin any unspecified fields be initialized to 0 and fill in a default value for them). However, when any caller that omits a field to get the default value is pestered with a warning, that approach does not really work well. On the other hand, disabling the warning completely with a commandline option or pragma seems heavy-handed, since I do consider this a useful warning in many other cases.
(In reply to Matthijs Kooijman from comment #11) > It seems this was actually implemented at some point (at least for C++, > maybe that was the case all along already), though the manual page was not > updated to reflect this. Sounds like a documentation issue, too, then; adding that keyword...