我应该如何从C ++正确初始化C结构?

时间:2011-01-24 13:38:16

标签: c++ cross-platform initialization

我在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++错误消息表明没有。

我有什么选择?

5 个答案:

答案 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

等等