为什么编译器抛出这个警告: “缺少初始化程序”? 结构没有被初始化吗?

我在为一个项目创建某种前端。为了启动程序,我使用了调用 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);

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

73287 次浏览

海湾合作委员会只是过于偏执了——在我看来没有什么好的理由,但是海湾合作委员会的维护人员确实比我更了解 C 的细微差别。

请参阅海湾合作委员会邮件列表中关于这个问题的讨论:

但是底线是-仅用 {0}初始化 struct 实际上将为零来初始化整个过程。

C99标准在6.7.8/21“初始化-语义”中说明了以下内容:

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

C90在6.5.7中的表达基本相同,只是措辞有些不同(换句话说,C99在这里没有添加新的内容)。

还要注意的是,在 C + + 中,这是扩展的,以便一个空的大括号集“ {}”,将对一个对象执行值初始化,因为有些情况(如模板) ,你甚至不知道什么成员或多少成员的类型可能有。因此,这不仅是一个好的实践,而且有时需要一个比对象可能拥有的成员数更短的初始化器列表。

对于 C + + 程序中的 GCC,可以通过将结构初始化为

STARTUPINFO startupInfo = STARTUPINFO();
  • 就在几天前

您要求尽可能多地使用 - Wall - 是的

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

您可以通过添加 - Wno-miss-field-initializer .

如何初始化所有元素的结构-zero-or-null 网页详细讨论了基本问题:

作为一种解决方案,我目前的解决方案是有选择地压制这一警告:

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

遗憾的是,这只在 中起作用,而在 GCC 中似乎不起作用。

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

例如:

T bla = boost::initialized_value;