gpt4 book ai didi

c++ - 具有原始类型的单个数组成员的标准布局结构的保证内存布局

转载 作者:IT老高 更新时间:2023-10-28 21:53:07 27 4
gpt4 key购买 nike

考虑以下简单结构:

struct A
{
float data[16];
};

我的问题是:

假设 float 是 32 位 IEEE754 float 的平台(如果这很重要的话),C++ 标准是否保证 struct A 的预期内存布局?如果不是,它保证什么和/或执行保证的方法是什么

预期内存布局是指结构占用内存中的16*4=64字节,每个连续的4字节占用通过 data 数组中的单个 float。换句话说,预期内存布局意味着以下测试通过:

static_assert(sizeof(A) == 16 * sizeof(float));
static_assert(offsetof(A, data[0]) == 0 * sizeof(float));
static_assert(offsetof(A, data[1]) == 1 * sizeof(float));
...
static_assert(offsetof(A, data[15]) == 15 * sizeof(float));

(offsetof 在这里是合法的,因为 A 是标准布局,见下文)

如果这让您感到困扰,请测试 actually passes在带有 gcc 9 HEAD 的魔杖盒上。我从来没有遇到过一个平台和编译器的组合可以提供这个测试可能会失败的证据,如果它们确实存在,我很想了解它们。

为什么还要关心:

  • 类似 SSE 的优化需要一定的内存布局(和对齐,我在这个问题中忽略了这一点,因为它可以使用标准的 alignas 说明符来处理)。
  • 这种结构的序列化可以简单地归结为一个漂亮且可移植的 write_bytes(&x, sizeof(A))
  • 一些 API(例如 OpenGL,特别是 glUniformMatrix4fv)期望这种精确的内存布局。当然,可以只传递指向 data 数组的指针来传递这种类型的单个对象,但是对于这些序列(例如,用于上传矩阵类型顶点属性),特定的内存布局是仍然需要。

实际保证的内容:

据我所知,这些是 struct A 可以预期的:

  • standard layout
  • 由于是标准布局,指向 A 的指针可以是 reinterpret_cast 指向其第一个数据成员(大概是 data[0] ?),即在第一个成员之前没有填充。

标准提供的其余两个(据我所知)保证是:

  • 原始类型数组的元素之间没有填充(我确信这是错误的,但我没有找到确认引用),
  • struct A内的data数组没有填充。

最佳答案

布局不能保证的一件事是字节序,即多字节对象中的字节顺序。 write_bytes(&x, sizeof(A)) 不是跨具有不同字节序的系统的可移植序列化。

A can be reinterpret_cast to a pointer to its first data member (which is, presumably, data[0] ?)

更正:第一个数据成员是 data,您可以使用它重新解释强制转换。至关重要的是,数组不能与其第一个元素指针互转换,因此您无法重新解释它们之间的强制转换。但是,地址保证是相同的,因此据我了解,在 std::launder 之后重新解释为 data[0] 应该没问题。

There is no padding in between elements of an array of primitive type

数组保证是连续的。对象的 sizeof 是根据将元素放入数组所需的填充来指定的。 sizeof(T[10]) 的大小正好是 sizeof(T) * 10。如果相邻元素的非填充位之间存在填充,则该填充位于元素本身的末尾。

原始类型一般不保证没有填充。例如,x86 扩展精度 long double 为 80 位,填充为 128 位。

charsigned charunsigned char 保证没有填充位。 C 标准(在这种情况下 C++ 将规范委托(delegate)给它)保证固定宽度的 intN_tuintN_t 别名没有填充位。在不可能的系统上,不提供这些固定宽度类型。

关于c++ - 具有原始类型的单个数组成员的标准布局结构的保证内存布局,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55650798/

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