gpt4 book ai didi

c++ - 在 C++ 中填充 C 结构的填充字节? (不涉及结构包装!)

转载 作者:搜寻专家 更新时间:2023-10-31 02:09:52 26 4
gpt4 key购买 nike

我正在使用一个带有 3 个正式记录成员的结构的库,但它的实现实际上包含 4 个。最后一个是用于填充的字节数组。这是 C 中保持 ABI 兼容的常用技术:在末尾添加一堆字节,如果以后的版本向结构添加成员,则此填充区域会相应缩小。总的来说,结构的大小保持不变。

但现在我必须在 C++ 中使用这个结构,并且我将它用于静态常量值,因此我需要使用初始化列表对其进行初始化。所以,像这样:

static const foo_struct foo = { 1, 2, 3 };

由于这没有初始化第四个值,GCC 打印出:

warning: missing initializer for member ‘foo_struct::padding’ [-Wmissing-field-initializers]

像 foo(1,2,3) 这样的构造器语法是行不通的,因为这是一个 C 结构。将它设置为 {0} 也是不可取的,因为我必须初始化前三个成员。

是否有符合 C++11/C++14 的方法来处理此警告?

编辑:简单地使用 { 1, 2, 3, 0 } 可能有效,但不稳定,因为填充区域未记录。另外,如果 future 的版本添加一个成员,那么它会加起来为 5 个成员,并且会返回警告。

最佳答案

你可以像这样写一个函数:

template <class ... T>
constexpr foo_struct make_foo_struct(T ... t) {
return foo_struct{t..., 0};
}

static const auto foo = make_foo_struct(1, 2, 3);

您不需要禁用任何警告。作为奖励,如果将另一个字段添加到结构中,警告将返回(因为您将有 5 个成员,而您只初始化 4 个)。这也很方便,因为如果你正在创建大量的 foos,并且添加了一个你不关心的新字段(比如它是一个 bool 值,你总是希望它是 true),你可以更改 make_foo_struct 以按照您想要的方式对其进行初始化,而无需修改所有调用站点。

你当然可以在 make_foo_struct 中写出类型和参数名称,而不是使用 T...;它使事情变得更明确,但也需要更多的维护和灵 active 。

如果删除了填充,这将无法编译,同样你只需要修复这个函数。但是,如果您不喜欢这样,另一种选择是使用编译器杂注在本地消除警告,就在函数中。

template <class ... T>
constexpr foo_struct make_foo_struct(T ... t) {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
return foo_struct{t...};
#pragma GCC diagnostic pop
}

见鬼去吧,我会给出第三种选择。如果你有 3 个命名成员,并且它们的名字是稳定的,你想简单地初始化它们并将其余的清零,你可以这样做:

constexpr foo_struct make_foo_struct(int x, int y, int z) {
foo_struct f{};
f.x = x; f.y = y; f.z = z;
return f;
}

编译器应该很乐意优化它。

关于c++ - 在 C++ 中填充 C 结构的填充字节? (不涉及结构包装!),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46081808/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com