我正在尝试在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);
}
答案 0 :(得分:3)
有两个原因,每个原因都足够了。
INT32
的大小是4个字节。 INT24
的大小也是4个字节,因为它包含INT32
位字段。由于myStruct
包含3个大小为4的成员,因此其大小必须至少为12。INT32
的对齐要求是4.因此,即使INT24
的大小为3,myStruct
的大小仍然必须为12,因为它必须有至少INT32
的对齐要求,因此myStruct
的大小必须填充到最接近的4的倍数。任何方式或解决方法?
这是特定于实现的,但以下hack可能适用于某些编译器/ 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 pack hack慢。
答案 1 :(得分:1)
遗憾的是,编译器在优化特定体系结构的代码时保留了通过在成员和之间插入空格来填充结构的权利,即使在结束时结构。
使用位字段不会减小struct
的大小;你仍然得到整个&#34;现场&#34;输入struct
。
该标准保证struct
的第一个成员的地址与struct
,的地址相同,除非是多态类型。
但一切都没有丢失:您可以依赖char
的数组将始终连续且不包含的事实。
如果在系统上将CHAR_BIT定义为8(可能是),则可以在char
的数组上为24位类型的数组建模。如果它不是8,那么即使这种方法也行不通:我建议采用内联汇编。