It looks like a gcc "consistency bug", here is the relevant code snippet in gcc/c/c-typeck.c
7436 /* Warn when some struct elements are implicitly initialized to zero. */
7437 if (warn_missing_field_initializers
7438 && constructor_type
7439 && TREE_CODE (constructor_type) == RECORD_TYPE
7440 && constructor_unfilled_fields)
7441 {
7442 bool constructor_zeroinit =
7443 (vec_safe_length (constructor_elements) == 1
7444 && integer_zerop ((*constructor_elements)[0].value));
7445
7446 /* Do not warn for flexible array members or zero-length arrays. */
7447 while (constructor_unfilled_fields
7448 && (!DECL_SIZE (constructor_unfilled_fields)
7449 || integer_zerop (DECL_SIZE (constructor_unfilled_fields))))
7450 constructor_unfilled_fields = DECL_CHAIN (constructor_unfilled_fields);
7451
7452 if (constructor_unfilled_fields
7453 /* Do not warn if this level of the initializer uses member
7454 designators; it is likely to be deliberate. */
7455 && !constructor_designated
7456 /* Do not warn about initializing with ` = {0}'. */
7457 && !constructor_zeroinit)
7458 {
7459 if (warning_at (input_location, OPT_Wmissing_field_initializers,
7460 "missing initializer for field %qD of %qT",
7461 constructor_unfilled_fields,
7462 constructor_type))
7463 inform (DECL_SOURCE_LOCATION (constructor_unfilled_fields),
7464 "%qD declared here", constructor_unfilled_fields);
7465 }
7466 }
The intent of the code appears to be to warn if any attribute constructor has an unfilled-field. The fact that you are not getting a warning on element 'a' is likely the "consistency bug" here.
If -Wextra
is intended to turn on the missing initializers warning, then it has. The question is, should the "missing initializers warning" exclude omitted attributes? It seems that gcc and clang disagree about this - and it might be fine for them to?
This may not be the answer you are looking for .. but hope it helps with your understanding of the situation. :). GCC team has a consistency bug, but their code's intent seems to be warn in these cases, whereas clang, empirically, will not.
a
at the same time. That inconsistency points to a bug. For reporting it to the GCC team, you can lose the header and theprintf()
and make it a general function rather thanmain
so that your preprocessed code is minimal. I compiled with-std=c11
, too, rather than-std=c99
. – Singleta
, and also there is no warning if the compound literal is applied to the last member of astruct
– Crewstruct T t = {.b = &t.a };
doesn't generate the warning, for example. A one-element array (compound literal) is sufficient, too. It also seems to be "only the element after the one initialized with the compound literal". Addint d;
afterc
and there's no complaint aboutd
. (Add more integers before or after, and it is still just the one element after the compound literal that gets the complaint.) – Singletstruct T { int a; int *b; int c; int *e; /* int f; */ };
andstruct T t = {.b = ((int []){1, 1}), .e=((int []){2,3})};
this won't. But remove the comment it will aboute
not aboutb
anymore. – Cyrstruct T { int a; int *b; int c; }; struct T foo(int bar); struct T foo(int bar) { struct T t = {.b = (int[]){1}}; t.c = bar; return t; }
which can be preprocessed without doing more than adding for#line
directives (except that theline
is left out). Which makes a close to minimal reproduction. I compile withgcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes -c diw71.c
('diw' — designated initializers warning; choose your own name). – Singletgcc
team here!. (S)he might give a better overview over this. – Cyr#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
as a (temporary) workaround. – Hebraize