C++11 为什么我会得到;警告:成员“”缺少初始值设定项;?[-Wmissing字段初始值设定项]

C++11 为什么我会得到;警告:成员“”缺少初始值设定项;?[-Wmissing字段初始值设定项],c++11,gcc,initialization,compiler-warnings,member,C++11,Gcc,Initialization,Compiler Warnings,Member,我想知道为什么在一种情况下会收到关于初始化的警告,而在另一种情况下却没有。代码在C++源文件中,使用GCC 4.7,代码< > STD= C++ 11 < /代码> ./P> 上述操作不会对-Wall和-Wextra产生警告 上述情况会产生警告: warning: missing initializer for member ‘sigaction::__sigaction_handler’ [-Wmissing-field-initializers] warning: missing ini

我想知道为什么在一种情况下会收到关于初始化的警告,而在另一种情况下却没有。代码在C++源文件中,使用GCC 4.7,代码< > STD= C++ 11 < /代码> ./P>
上述操作不会对
-Wall
-Wextra
产生警告


上述情况会产生警告:

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]

我已经通读了很多错误报告,比如。我不明白为什么未初始化的结构不生成警告,而初始化的结构生成警告


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

编译器会在初始化结构时警告所有成员未初始化。对于声明未初始化的结构,没有任何警告。当(部分)初始化未初始化的结构时,应该会收到相同的警告

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

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

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

如果你知道自己在做什么,就不要理会这个警告。我也经常收到这样的警告,而且我经常感到不安。但我对此无能为力,只能置之不理


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

下面是一个简单的例子:

#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;
}
函数“int main()”中缺少.cpp:
缺少.cpp:10:43:警告:“s.s::b”在此函数中未初始化使用[-Wuninitialized]
缺少.cpp:10:26:警告:“s.s::a”在此函数中未初始化使用[-Wuninitialized]

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

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


仅当您显式但部分初始化字段时,它才会发出警告。它提醒您,该结构的字段比您枚举的字段多。在我看来,这个警告有多有用值得怀疑:它确实会产生太多的假警报。嗯,默认情况下它没有打开是有原因的…

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

int main() {
  S s;
  std::cout<<"s.a = "<<s.a<<", s.b = "<<s.b<<std::endl;
}
#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;
}
#包括
#包括
类型定义结构{
INTA;
int b;
charc[12];
}测试类型;
int main(int argc,char*argv[]){
测试类型1;
memset(&type1,0,sizeof(testtype_t));
printf(“%d,%s,%d\n”,argc,argv[0],类型1.a);
返回0;
}

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

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

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


因此,是的,您可以使警告静音,不,这不是初始化struct sigaction的方式。

您所称的initialized只是部分初始化,因此警告。重复,但我不允许结束问题。唉…memset在某些情况下可能是错的,谢谢,这是有道理的。我可能会分裂C++头发,但是调用<代码> SigEnTyTys >不是C++用户所使用的初始化。通常的说法是C++中的赋值不是初始化,但我认为<代码> SigEnTySt/<代码>的用法是相似的。
int main() {
  S s;
  std::cout<<"s.a = "<<s.a<<", s.b = "<<s.b<<std::endl;
}
#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;
}