在C中,编译器将按照声明它们的顺序布置结构的成员,在成员之间插入可能的填充字节,或者在最后一个成员之后插入,以确保每个成员正确对齐.
gcc提供了一种语言扩展,__attribute__((packed))它告诉编译器不要插入填充,允许结构成员不对齐.例如,如果系统通常要求所有int对象都具有4字节对齐,则__attribute__((packed))可能导致int在奇数偏移处分配struct成员.
引用gcc文档:
`packed'属性指定变量或结构字段应该具有尽可能小的对齐 - 变量的一个字节和字段的一个位,除非您使用`aligned'属性指定更大的值.
显然,使用此扩展可以导致更小的数据要求但代码更慢,因为编译器必须(在某些平台上)生成代码,以便一次一个字节地访问未对齐的成员.
但有任何不安全的情况吗?编译器是否始终生成正确(但速度较慢)的代码来访问打包结构的未对齐成员?在所有情况下都可以这样做吗?
对于某些编译器,有一个结构的打包说明符,例如::
RealView ARM compiler has "__packed" Gnu C Compiler has "__attribute__ ((__packed__))" Visual C++ has no equivalent, it only has the "#pragma pack(1)"
我需要一些我可以放入结构定义的东西.
任何信息/黑客/建议?TIA ...
我在PC(mingw32,32bit arch)上模拟来自嵌入式系统(stm32,KeilμVision5,MDK-ARM)的代码.ARM编译器的对齐方式与我的桌面mingw构建不匹配:
// ARM Code (ARM compiler uses __packed)
typedef __packed struct _file
{
uint8_t var1;
uint16_t var2;
} FILE;
// PC mingw gcc code trying to emulate layout above.
typedef struct __attribute__((packed, aligned(1))) _file
{
uint8_t var1;
uint16_t var2;
} FILE;
Run Code Online (Sandbox Code Playgroud)
在源代码中,我执行以下操作:file.var1 = 0x22; file.var2 = 0xAA55;然后将其写入内存.当我读取它显示的嵌入式系统上的内存时0x22, 0x55, 0xAA.在Windows机器上读取0x22, 0xFF, 0x55, 0xAA,与在2填充第二个字节.我该如何纠正这种行为?