我在C ++文件中有以下代码:
#include <sys/socket.h>
// ...
void someFunc() {
struct msghdr msg = {0}; // <<< Uninitialized member here
}
当我使用g++
使用-Wall -Wextra
进行编译时,会收到警告:
error: missing initializer for member 'msghdr::msg_namelen'
...same for several other fields
我的问题是:我无法显式初始化所有字段,因为我不知道struct msghdr
中将存在哪些字段(跨平台)。该结构没有默认构造函数,因为它是一个C结构。我的印象是= {0}
形式导致所有字段的零初始化(这对我来说没问题),但g++
错误消息表明没有。
我有什么选择?
答案 0 :(得分:8)
void someFunc()
{
msghdr msg = {}; // <<< All members zero-initialized
}
g ++ -Wextra
警告级别是恕我直言并不是很有用。
你所拥有的代码对于“C struct”来说也是正式的,在称为POD(Plain Old Data)的标准中。但是你的代码用0显式初始化第一个成员。这不一定适用于非POD的聚合,例如使用std::string
作为第一个成员,而纯{}
也适用于此。
顺便说一句,通常像你正在处理的那个POD有一个字节数作为第一个成员,然后你可以这样做......
void foo()
{
SomePODStruct o = {sizeof(o)}; // The other members zero-initialized.
}
也许添加STATIC_ASSERT
字节计数成员是第一个(在偏移0处)。
干杯&amp;第h。,
答案 1 :(得分:4)
这应该有效:
memset(&msg, 0, sizeof(msg));
答案 2 :(得分:2)
导致此问题的特定警告标记为-Wmissing-field-initializers
,该标记已作为-Wextra
的一部分启用。因此,避免此(伪造)警告的最简单方法是使用-Wno-missing-field-initializers
。
答案 3 :(得分:1)
如果你不能忍受警告和/或不想禁用警告,那么我认为它必须通过例如明确的初始化。 memset的:
memset(&msg, 0, sizeof(msg));
答案 4 :(得分:0)
如果你不想使用默认构造函数,你可以简单地使用预处理器函数,如:
#ifdef LINUX
//init for linux
#endif
#ifdef WINDOWS
//init for windows
#endif
等等