为啥 MinGW 4.9 显示缺少根据标准正确的代码的初始化程序警告
Posted
技术标签:
【中文标题】为啥 MinGW 4.9 显示缺少根据标准正确的代码的初始化程序警告【英文标题】:Why MinGW 4.9 shows missing initializer warning for code that is correct according to standards为什么 MinGW 4.9 显示缺少根据标准正确的代码的初始化程序警告 【发布时间】:2014-12-17 08:26:07 【问题描述】:我有这个用于 MS windows 的代码:
#include <windows.h>
#include <Shellapi.h>
#include <tchar.h>
#include <string>
void foo()
SHELLEXECUTEINFO shExInfo = 0;
根据这个回答What Does 0 Mean in C++?
这里发生的事情称为聚合初始化。这里是 (缩写)来自 ISO 8.5.1 节的聚合定义 规格:
聚合是没有用户声明的数组或类 构造函数,没有私有或受保护的非静态数据成员,没有基 类,没有虚函数。
这段代码可以编译,但是在 MinGW 4.9 上它会抛出:
warning: missing initializer for member '_SHELLEXECUTEINFOW::lpParameters' [-Wmissing-field-initializers]
对于 SHELLEXECUTEINFO 结构的每一部分
这是为什么呢?规格有什么变化吗?注意:这段代码是c++11
【问题讨论】:
如果你使用 C++11,那么你应该做例如SHELLEXECUTEINFO shExInfo;
【参考方案1】:
为什么会这样?
因为您已要求编译器针对此类情况发出警告,方法是使用 -Wmissing-field-initializers
指定此特定错误,或使用 -Wextra
或类似的更多警告。
通常,警告是针对有效但可能指示错误的代码。在这种情况下,它可能表明您忘记初始化需要初始化的东西,或者只是您想要默认行为。
如果您不喜欢此警告,并且不想更改代码以显式初始化所有字段,则可以使用 -Wno-missing-field-initializers
禁用它。
规格有什么变化吗?
不,只为聚合的某些字段提供初始化程序仍然有效。这就是为什么它只是一个警告,而不是一个错误。
注意:这段代码是c++11
然后我将其更改为 SHELLEXECUTEINFO shExInfo ;
以指定值初始化。这将对所有字段进行零初始化,而不会触发任何警告。在较旧的方言中,=
应该具有相同的效果。
【讨论】:
我很困惑,因为 MSVC 编译器根本不会对该代码触发任何警告,这是有道理的,我相信这段代码取自 msdn 示例。 顺便说一句,使用 SHELLEXECUTEINFO shExInfo ;产生相同的警告:/它需要被显式禁用,我发现这非常复杂,当您正在执行要在十几个编译器上编译的跨平台代码时。 (此代码块是特定于 windows 的,但编译器标志是通过 cmake 处理的)【参考方案2】:规范没有任何变化,这只是一个警告,如果需要,它会提醒您为聚合的所有字段指定显式初始化程序。
Meanfile,您编写的初始化程序从语言的角度来看是完全合法的。
根据-Wmissing-field-initializers
的规范,您可以将初始化程序缩短为=
。最终效果将是相同的,但没有警告。 IE。这是告诉编译器即使在存在-Wmissing-field-initializers
的情况下您确实希望依赖于字段的隐式值初始化的方式。
但更好的办法是检查您启用-Wmissing-field-initializers
的原因。这是抱怨许多非常有用的编程习惯的“极端”警告选项之一。 -Wmissing-field-initializers
甚至不包含在 -Wall
中。它是-Wextra
的一部分。
【讨论】:
以上是关于为啥 MinGW 4.9 显示缺少根据标准正确的代码的初始化程序警告的主要内容,如果未能解决你的问题,请参考以下文章
为啥 mingw bin 目录中的 c++fit 无法返回预期结果?