9

The code

  GValue value = { 0 };

gives the following warning:

missing initializer [-Wmissing-field-initializers]

I know that's a GCC bug, but is there some trick to remove it? It is really not nice see such unreal warnings. But I don't want power off the warning because it will hide real warnings from me too. And sorry, but I can't update my GCC to 4.7 (where looks like it was fixed) version, yet.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jack
  • 16,276
  • 55
  • 159
  • 284
  • 3
    I highly doubt that it is a gcc bug. Could you show us the structure definition of GValue. – CCoder Nov 14 '12 at 05:51
  • it's just an example; I'm looking for a solution that works for any struct. – Jack Nov 14 '12 at 05:52
  • @GajananH I think we can assume that it's a GLib GValue — which means that it has more than one member (and indeed, what worthwhile struct *doesn't* have more than one member?) – hobbs Nov 14 '12 at 05:53
  • @hobbs: independent how many members the struct have, by using `{0}` all members shall be set to `0`. It's described in the C standard, as you can see in the link in my post. – Jack Nov 14 '12 at 05:56
  • 5
    There's no bug. According to the standard, a conforming implementation can issue diagnostic messages for any reason whatsoever, including cosmetic reasons, as long as it still accepts valid programs (i.e. it's a warning and not an error). You may disable this specific warning. – n. m. could be an AI Nov 14 '12 at 06:21
  • Perhaps I'm splitting hairs, but what version of C or C++ are you compiling against? That could well be a valid warning in, for example, C89 (does anyone even use it anymore?) – jww Nov 14 '12 at 07:39

3 Answers3

11

Use G_VALUE_INIT to initialize GValue-s. Their (private) structure is in /usr/include/glib-2.0/gobject/gvalue.h which #define G_VALUE_INIT appropriately.

I strongly disagree with your assessment that it is GCC's bug. You ask to be warned if a field is not explicitly initialized with -Wmissing-field-initializers and you get the warning you deserve.

Sadly G_VALUE_INIT is not documented, but it is here. Code with

GValue value = G_VALUE_INIT;

There is no universal solution to never get the warning about missing field initialization if -Wmissing-field-initializers is asked. When you ask for such a warning, you require the compiler to warn of every incomplete initializers. Indeed, the standard requires than all the non-explicitly initialized struct fields be zeroed, and gcc obeys the standard.

You could use diagnostic pragmas like

#pragma GCC diagnostic ignored "-Wmissing-field-initializers"

But my feeling is that you should code with care, and explicitly initialize all the fields. The warning you get is more a coding style warning (maybe you forgot a field!) than a bug warning.

I also believe that for your own (public) struct you should #define an initializing macro, if such struct are intended to be initialized.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • "I strongly disagree with your assessment that it is GCC's bug" - Agreed. Taking it a step further, initialize everything and let the optimizer discard spurious loads. It gets old tracking down these sorts of bugs because a programmer is trying to be clever (and the memory manager did not serve up a page that was zero'd). – jww Nov 14 '12 at 07:31
  • 8
    But it *is* a bug. `{0}` is what's called the "universal zero initializer", and when one uses it, one is **explicitly** initializing all fields to their logical zero. It thus makes no sense for GCC (or Clang, or any other compiler) to emit such a warning on such cases. – pwseo May 11 '13 at 16:10
  • 5
    @pwseo Old post, but your statement is not correct. The C language does _not_ treat `{0}` as a special case. There is no such thing as an "universal zero initializer" nor is `{0}` a way to explicitly initialize the whole array/struct. `{0}` simply means: _initialize the very first element to zero, and then let every other member get initialized just as if they had static storage duration, which is done implicitly_. And that is why `{1}` only initializes the first element to 1 and the rest to zero, it works exactly the same. – Lundin Mar 05 '14 at 10:08
  • 5
    @Lundin indeed, `{0}` is not the "universal zero initializer", but `{}` IS the "universal initializer", that will, as per the standard, *always* fill a structure with 0 for fields with no user-defined initializers/no constructor. This language facility is often used because 0 is what the programmer usually wants. Many times this is used with C structures with (obviously) no initializer, and no possibility to add ones. The warning is a (very annoying) GCC bug. Why adding adding non-required, non-useful constraints that will distract the programmer from the actual stuff ? – aberaud Sep 13 '14 at 20:06
  • 1
    @aberaud Huh? Empty initializer lists are not allowed in C, see C11 6.7.9 or read [this](http://stackoverflow.com/questions/17589533/is-an-empty-initializer-list-valid-c-code). Also, constructors are of no concern, as there are no constructors in the C language. – Lundin Sep 15 '14 at 06:31
  • @Lundin Yes, that is the point: C structures (with no constructors/initializers) can be 0-initialized in C++ by using `{}`, and that is totally valid and standard-compliant, because the code is compiled as C++, not C. – aberaud Sep 15 '14 at 16:34
  • 2
    You can use `{0,}` (note the comma) to initialise all fields to zero, but it will choke on some struct layouts. This is as close as C gets to a ‘universal zero initialiser’. If you *really* want a universal zero initialiser, use `memset()` on the struct instance. – Philip Withnall Oct 01 '18 at 11:32
11

You could use:

-Wno-missing-field-initializers

to inhibit that warning specifically. Conversely, you could make it into an error with:

-Werror=missing-field-initializers

Both of these work with GCC 4.7.1; I believe they work with GCC 4.6.x too, but they don't work with all earlier versions of GCC (GCC 4.1.2 recognizes -Wno-missing-field-initializers but not -Werror=missing-field-intializers).

Obviously, the other way to suppress the warning is to initialize all fields explicitly. That can be painful, though.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
2

It also appears that using the .field-style of initialization, such as:

GValue value = { .somefield = 0 };

will cause the compiler to not issue the warning. Unfortunately if the struct is opaque, this is a non-starter.

John Hascall
  • 9,176
  • 6
  • 48
  • 72
  • With recent gcc versions, this might no longer be true (I've seen the same warning on a different codebase using a designated initializer like you show, with arm-gcc 8). – Matthijs Kooijman Nov 22 '19 at 18:32
  • Interesting. IIRC the C standard requires that all unnamed fields be initialized to their zero value with this construct. So there are no uninitialized fields. – John Hascall Nov 22 '19 at 19:33
  • I believe it *does* zero-initialize, just warns about the missing explicit initializers. Also, it seems this warning only happens for C++, not C code. See also https://gcc.gnu.org/bugzilla/show_bug.cgi?id=39589 – Matthijs Kooijman Nov 23 '19 at 13:23