简体   繁体   English

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

[英]How should I properly initialize a C struct from C++?

I have the following code in a C++ file:我在 C++ 文件中有以下代码:

#include <sys/socket.h>

// ...
void someFunc() {
    struct msghdr msg = {0};  // <<< Uninitialized member here
}

When I compile with g++ using -Wall -Wextra , I get warnings:当我使用g++使用-Wall -Wextra进行编译时,我收到警告:

error: missing initializer for member 'msghdr::msg_namelen'
...same for several other fields

My problem is this: I can't explicitly initialize all the fields, because I don't know what fields will exist (cross-platform) in a struct msghdr .我的问题是:我无法显式初始化所有字段,因为我不知道struct msghdr中将存在哪些字段(跨平台)。 The struct doesn't have a default constructor, since it's a C struct.该结构没有默认构造函数,因为它是 C 结构。 I was under the impression that the = {0} form led to zero-initialization of all fields (which would be fine for me), but the g++ error message suggests not.我的印象是= {0}表单导致所有字段的零初始化(这对我来说很好),但g++错误消息表明不是。

What are my options here?我在这里有什么选择?

void someFunc()
{
    msghdr msg = {};  // <<< All members zero-initialized
}

The g++ -Wextra warning level is IMHO not very useful. g ++ -Wextra警告级别是恕我直言不是很有用。

The code that you have is also formally OK for a "C struct", in standardeese known as POD (Plain Old Data). 您所拥有的代码对于称为POD(Plain Old Data)的标准“C结构”也是正式的。 But your code explicitly initializes first member with 0. That won't necessarily work for an aggregate that isn't POD, eg with a std::string as first member, while the pure {} will work also for that. 但是你的代码用0显式初始化第一个成员。这不一定适用于非POD的聚合,例如std::string作为第一个成员,而pure {}也适用于此。

In passing, often a POD like the one you're dealing with has a byte count as first member, and then you can do like … 顺便说一句,通常像你正在处理的那个POD有一个字节数作为第一个成员,然后你可以这样做......

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

Perhaps add a STATIC_ASSERT that the byte count member is first (at offset 0). 也许添加字节计数成员为第一个的STATIC_ASSERT (偏移量为0)。

Cheers & hth., 干杯&hth。,

这应该工作:

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

The specific warning flag that causes this is -Wmissing-field-initializers , which is turned on as part of -Wextra . 导致这种情况的特定警告标志是-Wmissing-field-initializers ,它作为-Wextra一部分-Wextra The simplest way to avoid this (bogus) warning is therefore to use -Wno-missing-field-initializers . 因此,避免此(伪造)警告的最简单方法是使用-Wno-missing-field-initializers

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

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

maybe if you don't want to use default constructor you can simply use preprocessor functions like: 也许如果你不想使用默认构造函数,你可以简单地使用预处理器函数,如:

#ifdef LINUX
//init for linux
#endif

#ifdef WINDOWS
//init for windows
#endif

and so on 等等

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM