为什么我会收到“警告:缺少会员的初始化程序”? [-Wmissing场-初始化]

时间:2014-02-09 11:27:56

标签: gcc c++11 initialization compiler-warnings members

我想知道为什么我在一个案例中得到关于初始化的警告,而不是另一个案例。代码位于C ++源文件中,并使用GCC 4.7和-std=c++11


struct sigaction old_handler, new_handler;

以上内容产生了-Wall-Wextra NO 警告。


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

以上产生警告:

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]

我已阅读How should I properly initialize a C struct from C++?Why is the compiler throwing this warning: "missing initializer"? Isn't the structure initialized?以及http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36750等错误报告。我不明白为什么未初始化的struct 不是生成警告,而初始化的struct 生成警告。

为什么未初始化的结构没有生成警告;为什么初始化的结构生成警告?

5 个答案:

答案 0 :(得分:8)

这是一个简单的例子:

#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;
}

它发出警告:

  

missing.cpp:在函数'int main()'中:
  missing.cpp:9:11:警告:缺少成员'S :: b'的初始值设定项[-Wmissing-field-initializers]

程序打印:

  

s.a = 1,s.b = 0

警告只是来自编译器的提示,S有两个成员,但您只显式初始化其中一个,另一个将设置为零。如果这是您想要的,您可以放心地忽略该警告。

在这么简单的例子中,它看起来很傻和烦人;如果您的结构有很多成员,那么这个警告可能会有所帮助(捕获错误:错误计算字段数或拼写错误)。


  

为什么未初始化的结构不会产生警告?

我想这只会产生太多的警告。毕竟,它是合法的,如果您使用未初始化的成员,这只是一个错误。例如:

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

missing.cpp:在函数'int main()'中:
  missing.cpp:10:43:警告:'s.S :: b'在此函数中未初始化使用[-Wuninitialized]
  missing.cpp:10:26:警告:'s.S :: a'在此函数中未初始化使用[-Wuninitialized]

即使它没有警告我s的未初始化成员,它确实警告我使用未初始化的字段。一切都很好。

  

为什么初始化的结构会产生警告?

只有在您明确但部分初始化字段时才会向您发出警告。这提醒一下,struct包含的字段多于您枚举的字段。在我看来,这个警告有多么有用是值得怀疑的:它确实会产生太多的错误警报。嗯,由于某种原因,它默认不启用...

答案 1 :(得分:3)

这是一个有缺陷的警告。您确实初始化了所有成员,您只是没有为每个成员分别出现在代码中的初始值设定项。

如果您知道自己在做什么,请忽略该警告。我经常得到这样的警告,我经常不高兴。但我无能为力,只能忽略它。

为什么未初始化的结构没有发出警告?我不知道,但很可能是因为你没有尝试初始化任何东西。所以GCC没有理由相信你在初始化时犯了一个错误。

答案 2 :(得分:2)

编译器警告初始化结构时不会初始化所有成员。没有什么可以警告声明一个未初始化的结构。当(部分)初始化未初始化的结构时,您应该得到相同的警告。

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

所以,这就是区别。您的代码不会产生警告,根本不是初始化。为什么gcc警告零初始化结构根本不在我身上。

答案 3 :(得分:1)

防止该警告(或错误,如果您或您的组织将警告视为错误(-Werror选项))的唯一方法是将其设置为初始值。例如:

#include <stdio.h>
#include <memory.h>

typedef struct {
    int a;
    int b;
    char c[12];
} testtype_t;

int main(int argc, char* argv[]) {
    testtype_t type1;

    memset(&type1, 0, sizeof(testtype_t));

    printf("%d, %s, %d\n", argc, argv[0], type1.a);
    return 0;
}

然而,对于GCC维护者来说,不是很干净,只有一种方法可以初始化一个结构,并且代码美不在他们的列表之上。

答案 4 :(得分:1)

您正在解决症状但不是问题。根据我在UNIX环境中的高级编程副本,第二版&#34;在第10.15节:

  

请注意,我们必须使用sigemptyset()来初始化结构的sa_mask成员。我们不保证act.sa_mask = 0做同样的事情。

所以,是的,你可以使警告静音,而且这不是你如何初始化结构sigaction。