gpt4 book ai didi

c++ - 打包 union/结构以避免填充

转载 作者:行者123 更新时间:2023-12-04 13:07:27 31 4
gpt4 key购买 nike

我有一个看起来像这样的结构:

struct vdata {
static_assert(sizeof(uint8_t *) == 8L, "size of pointer must be 8");
union union_data {
uint8_t * A; // 8 bytes
uint8_t B[12]; // 12 bytes
} u;
int16_t C; // 2 bytes
int16_t D; // 2 bytes
};

我想把它设为 16 字节,但 GCC 告诉我它是 24,因为 union 正在填充到 16 字节。

我想将 vdata 放入一个大的 std::vector 中。根据我的理解,如果这是 16 个字节,则对齐应该没有问题,因为指针始终是 8 个字节对齐的。

我知道我可以在 GCC 中使用 __attribute__((__packed__)) 强制打包它。但我想知道是否有一种可移植且符合标准的方法可以将其设置为 16 字节?


编辑:想法

思路一:拆分B数组。

struct vdata {
union union_data {
uint8_t * A; // 8 bytes
uint8_t B[8]; // 8 bytes
} u;
uint8_t B2[4]; // 4 bytes
int16_t C; // 2 bytes
int16_t D; // 2 bytes
};

可以从 B 的指针可靠地访问 B2 元素吗?这是定义的行为吗?

想法 2:将指针存储为字节数组并根据需要存储 memcpy (@Eljay)

struct vdata {
union union_data {
std::byte A[sizeof(uint8_t*)]; // 8 bytes
uint8_t B[12]; // 12 bytes
} u;
int16_t C; // 2 bytes
int16_t D; // 2 bytes
};

访问指针会导致性能下降,还是会被优化掉? (假设 GCC x86)。

最佳答案

您可以将 A 更改为 std::byte A[sizeof(uint8_t*)]; 然后将 std::memcpy 指针进入 A 并离开 A

关于正在发生的事情值得评论,这些额外的环是为了避免填充字节。

同时添加一个 set_A setter 和 get_A getter 可能会很有帮助。

struct vdata {
union union_data {
std::byte A[sizeof(uint8_t*)]; // 8 bytes
uint8_t B[12]; // 12 bytes
} u;
int16_t C; // 2 bytes
int16_t D; // 2 bytes

void set_A(uint8_t* p) {
std::memcpy(u.A, &p, sizeof p);
}
uint8_t* get_A() {
uint8_t* result;
std::memcpy(&result, u.A, sizeof result);
return result;
}
};

关于c++ - 打包 union/结构以避免填充,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68747627/

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