我正在为一个程序创建某种前端。为了启动程序,我使用了调用
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);
这样编译器就不会给出任何警告。 问题是,这些初始化结构的方式有什么区别? 使用第一种方法,结构体不是已经初始化了吗? 您推荐哪一款?
GCC 只是过于偏执 - 在我看来没有充分的理由,但 GCC 维护者确实比我更了解 C 的细微差别。
请参阅 GCC 邮件列表上关于该问题的小讨论:
底线 - 仅使用
{0}
初始化结构实际上会将整个事物初始化为零。
C99 标准在 6.7.8/21“初始化 - 语义”中说明了以下内容:
如果大括号括起来的列表中的初始值设定项少于聚合的元素或成员,或者用于初始化已知大小的数组的字符串文字中的字符少于数组中的元素,则聚合的其余部分应与具有静态存储持续时间的对象一样隐式初始化。
C90 在 6.5.7 中说的基本相同,但措辞略有不同(换句话说,C99 没有在这里添加新内容)。
另请注意,在 C++ 中,这已被扩展,以便一组空的大括号“
{}
”将对对象执行值初始化,因为在某些情况下(例如模板),您甚至不知道成员是什么或如何进行一个类型可能有许多成员。因此,这不仅是一个好的实践,而且有时有必要拥有一个比对象可能拥有的成员数量短的初始化列表。
通过将结构初始化为 C++ 程序中的 GCC,可以轻松修复此问题
STARTUPINFO startupInfo = STARTUPINFO();
在这种情况下,您会收到一条警告,告诉您没有指定所有字段,这是完全有效的,但可能是无意的。
您可以通过添加来抑制此警告 -Wno-missing-field-initializers.
网页如何将结构初始化为全元素零或空详细讨论了根本问题:
作为解决方法,我当前的解决方案是有选择地抑制此警告:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wmissing-field-initializers"
STARTUPINFO startupInfo = {0};
#pragma clang diagnostic pop
遗憾的是,这仅适用于 Clang,并且似乎不适用于 GCC。
在 C++ 中,您可以使用
boost::initialized_value
来消除此警告。我已关闭 boost
的警告;所以我不知道这是否会导致您的情况出现任何其他警告。这样您就不必禁用警告。
示例:
T bla = boost::initialized_value;