为什么使用 24 位整数时结构大小不会改变

why size of structure does not change when use 24 bit integer

本文关键字:改变 结构 整数 为什么      更新时间:2023-10-16

我正在尝试在Windows平台中移植嵌入代码。 我遇到了以下问题,我在这里发布示例代码。 即使在我使用 int24 之后,这里的大小在 Windows 中仍然是 12 字节,为什么?

struct INT24
{
INT32 data : 24;
};
struct myStruct
{
INT32 a;
INT32 b;
INT24 c;
};
int _tmain(int argc, _TCHAR* argv[])
{
unsigned char myArr[11] = { 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0xFF,0xFF,0xFF };
myStruct *p = (myStruct*)myArr;
cout << sizeof(*p);
}

有两个原因,每个原因本身就足够了。

  • 据推测,INT32的大小为 4 个字节。INT24的大小也是 4 个字节,因为它包含一个INT32位字段。由于myStruct包含 3 个大小为 4 的成员,因此其大小必须至少为 12。
  • 据推测,INT32的对齐要求是 4。因此,即使INT24的大小为 3,myStruct的大小仍必须为 12,因为它必须至少具有INT32的对齐要求,因此myStruct的大小必须填充到最接近的 4 的倍数。

任何方法或解决方法?

这是特定于实现的,但以下技巧可能适用于某些编译器/CPU 组合。有关类似功能的语法,请参阅编译器手册,以及目标 CPU 是否支持未对齐的内存访问的手册。还要意识到未对齐的内存访问确实会降低性能。

#pragma pack(push, 1)
struct INT24
{
INT32 data : 24;
};
#pragma pack(pop)
#pragma pack(push, 1)
struct myStruct
{
INT32 a;
INT32 b;
INT24 c;
};
#pragma pack(pop)

打包位字段可能不是在所有编译器中都相同。请务必检查您的行为。

我认为一种标准的兼容方法是存储大小为 3 和 4 的 char 数组,每当您需要读取或写入其中一个整数时,您都必须std::memcpy该值。实施起来会有点麻烦,也可能比 #pragma 包黑客慢。

可悲的是,编译器在优化特定体系结构的代码时保留通过在成员之间甚至在结构末尾插入空格来填充结构的权利。

使用位字段不会减小struct的大小;您仍然可以在struct中获得整个"fielded"类型。

该标准保证struct的第一个成员的地址与struct的地址相同,除非它是多态类型。

但一切都不会丢失:您可以依靠这样一个事实,即char数组始终是连续的并且不包含包装。

如果系统上将CHAR_BIT定义为 8(可能是),则可以在char数组上对 24 位类型的数组进行建模。如果不是 8,那么即使这种方法也行不通:然后我建议诉诸内联汇编。