Why do I get "warning: missing initializer for member"? [-Wmissing-field-initializers]

jww picture jww · Feb 9, 2014 · Viewed 22.3k times · Source

I'm wondering why I am getting a warning about initialization in one case, but not the other. The code is in a C++ source file, and using GCC 4.7 with -std=c++11.


struct sigaction old_handler, new_handler;

The above produces NO warnings with -Wall and -Wextra.


struct sigaction old_handler={}, new_handler={};
struct sigaction old_handler={0}, new_handler={0};

The above produces warnings:

warning: missing initializer for member ‘sigaction::__sigaction_handler’ [-Wmissing-field-initializers]
warning: missing initializer for member ‘sigaction::sa_mask’ [-Wmissing-field-initializers]
warning: missing initializer for member ‘sigaction::sa_flags’ [-Wmissing-field-initializers]
warning: missing initializer for member ‘sigaction::sa_restorer’ [-Wmissing-field-initializers]

I've read through How should I properly initialize a C struct from C++?, Why is the compiler throwing this warning: "missing initializer"? Isn't the structure initialized?, and bug reports like http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36750. I don't understand why the uninitialized struct is not generating a warning, while the initialized struct is generating a warning.

Why is the uninitialized structs not generating a warning; and why is the initialized structs generating a warning?

Answer

Ali picture Ali · Feb 9, 2014

Here is a simple example:

#include <iostream>

struct S {
  int a;
  int b;
};

int main() {
  S s { 1 }; // b will be automatically set to 0
             // and that's probably(?) not what you want
  std::cout<<"s.a = "<<s.a<<", s.b = "<<s.b<<std::endl;
}

It gives the warning:

missing.cpp: In function ‘int main()’:
missing.cpp:9:11: warning: missing initializer for member 'S::b' [-Wmissing-field-initializers]

The program prints:

s.a = 1, s.b = 0

The warning is just a reminder from the compiler that S has two members but you only explicitly initialized one of them, the other will be set to zero. If that's what you want, you can safely ignore that warning.

In such a simple example, it looks silly and annoying; if your struct has many members, then this warning can be helpful (catching bugs: miscounting the number of fields or typos).


Why is the uninitialized structs not generating a warning?

I guess it would simply generate too much warnings. After all, it is legal and it is only a bug if you use the uninitialized members. For example:

int main() {
  S s;
  std::cout<<"s.a = "<<s.a<<", s.b = "<<s.b<<std::endl;
}

missing.cpp: In function ‘int main()’:
missing.cpp:10:43: warning: ‘s.S::b’ is used uninitialized in this function [-Wuninitialized]
missing.cpp:10:26: warning: ‘s.S::a’ is used uninitialized in this function [-Wuninitialized]

Even though it did not warn me about the uninitialized members of s, it did warn me about using the uninitialized fields. All is fine.

Why is the initialized structs generating a warning?

It warns you only if you explicitly but partially initialize the fields. It is a reminder that the struct has more fields than you enumerated. In my opinion, it is questionable how useful this warning is: It can indeed generate too much false alarms. Well, it is not on by default for a reason...