为啥 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 显示缺少根据标准正确的代码的初始化程序警告的主要内容,如果未能解决你的问题,请参考以下文章

Qt5.4.2Mingw编译配置opencv2.4.9

为啥 mingw bin 目录中的 c++fit 无法返回预期结果?

为啥自定义光标图像显示不正确?

求解为啥qt5.7.0缺少对应的编译器

为啥 Frame.Width 和 Frame.Height 返回非常不正确的值

为啥使用 Seaborn 绘制回归时截距显示不正确?