我想知道为什么我在一个案例中得到关于初始化的警告,而不是另一个案例。代码位于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 是生成警告。
为什么未初始化的结构没有生成警告;为什么初始化的结构生成警告?
答案 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。