【问题标题】:How should I properly initialize a C struct from C++?我应该如何从 C++ 正确初始化 C 结构?
【发布时间】:2011-06-14 12:50:11
【问题描述】:

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

我有什么选择?

【问题讨论】:

标签: c++ cross-platform initialization


【解决方案1】:
void someFunc()
{
    msghdr msg = {};  // <<< All members zero-initialized
}

g++ -Wextra 警告级别恕我直言不是很有用。

您所拥有的代码在形式上也适用于“C 结构”,在称为 POD(Plain Old Data)的标准术语中。但是您的代码用 0 显式初始化第一个成员。这不一定适用于不是 POD 的聚合,例如std::string 作为第一个成员,而纯 {} 也适用于此。

顺便说一句,像您正在处理的 POD 通常有一个字节数作为第一个成员,然后您可以这样做......

void foo()
{
    SomePODStruct o = {sizeof(o)};    // The other members zero-initialized.
}

也许添加一个 STATIC_ASSERT 字节计数成员是第一个(在偏移量 0 处)。

干杯,

【讨论】:

  • 我不同意这句话g++ -Wextra 警告级别不是很有用
  • @peoro:好的。我添加了一个“恕我直言”。 :-)
【解决方案2】:

这应该可行:

memset(&msg, 0, sizeof(msg));

【讨论】:

  • 修正你的错字,我会删除我的答案,你秒杀我! :)
【解决方案3】:

导致此问题的特定警告标志是-Wmissing-field-initializers,它作为-Wextra 的一部分打开。因此,避免这种(虚假)警告的最简单方法是使用-Wno-missing-field-initializers

【讨论】:

    【解决方案4】:

    如果您不能忍受警告和/或不想禁用警告,那么我认为它必须通过例如显式初始化内存集:

    memset(&msg, 0, sizeof(msg));
    

    【讨论】:

      猜你喜欢
      • 2019-02-20
      • 1970-01-01
      • 1970-01-01
      • 2017-01-06
      • 2011-08-20
      • 2014-01-28
      • 1970-01-01
      • 1970-01-01
      • 2012-07-16
      相关资源
      最近更新 更多