为什么编译器会抛出此警告:“缺少初始化程序”?结构是否初始化?

时间:2009-10-08 16:26:46

标签: c winapi gcc

我正在为程序创建某种前端。要启动程序,我正在使用调用CreateProcess(),其中包含一个指向STARTUPINFO结构的指针。要初始化我曾经做过的结构:

STARTUPINFO startupInfo = {0}; // Or even '\0'.
startupInfo.cb = sizeof(startupInfo);

当使用GCC编译程序启用这些警告-Wall -Wextra时,它会给我一个警告,说明缺少初始化程序指向第一行。

warning: missing initializer
warning: (near initialization for 'startupInfo.lpReserved')

所以我最终做了:

STARTUPINFO startupInfo;
memset(&startupInfo, 0, sizeof(startupInfo));
startupInfo.cb = sizeof(startupInfo);

这样编译器就不会发出任何警告。 问题是,这些初始化结构的方式有什么区别? 使用第一种方法,是不是初始化了结构? 你会推荐哪一个?

5 个答案:

答案 0 :(得分:80)

海湾合作委员会只是过于偏执 - 我认为没有充分的理由,但是GCC维护人员对我所做的C的细微差别了解得更多。

在GCC邮件列表中查看关于该问题的这个小讨论线程:

但是底线 - 用{0}初始化结构实际上将零初始化整个事物。

C99标准在6.7.8 / 21“初始化 - Sematics”中说明如下:

  

如果括号括起的列表中的初始值设定项少于聚合的元素或成员,或者用于初始化已知大小的数组的字符串文字中的字符数少于数组中的元素,则剩余的聚合应隐式初始化,与具有静态存储持续时间的对象相同。

C90在6.5.7中表示基本相同,但措辞略有不同(换句话说,C99在这里没有添加任何新内容)。

另请注意,在C ++中,这是扩展的,因此一组空的大括号“{}”将对对象执行值初始化,因为有些情况(如模板)甚至不知道什么成员或类型可能有多少成员。因此,不仅是良好的做法,而且有时必须要有一个初始化列表,该列表比对象可能拥有的成员数量短。

答案 1 :(得分:17)

通过将结构初始化为

,可以在C ++程序中轻松修复GCC
STARTUPINFO startupInfo = STARTUPINFO();
  • 几天前就完成了这件事

答案 2 :(得分:12)

您要求使用尽可能多的警告 -Wall -Wextra。

在这种情况下,您会收到一条警告,告诉您未指定所有字段,这些字段完全有效,但可能是无意的。

您可以通过添加来抑制此警告 -Wno缺失场-初始化

答案 3 :(得分:8)

此网页详细讨论了基本问题: http://ex-parrot.com/~chris/random/initialise.html

作为解决方法,我目前的解决方案是有选择地禁止此警告:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wmissing-field-initializers"
STARTUPINFO startupInfo = {0};
#pragma clang diagnostic pop

可悲的是,这只适用于铿锵声,似乎不适用于海湾合作委员会。

答案 4 :(得分:1)

在C ++中,您可以使用boost::initialized_value来消除此警告。我已关闭boost的警告;所以我不知道这是否会导致你的任何其他警告。这样您就不必禁用警告。

示例:

T bla = boost::initialized_value;