我的结构如下
成员1,16位
成员2,32位
成员3,32位
我将从一个文件中读取我想直接从文件读入结构。
问题是,C编译器会将变量m1、m2和m3与32位的字边界对齐,因为我正在为以下结构声明处理ARM Cortex m3:
typedef struct
{
uint16_t m1;
uint32_t m2;
uint32_t m3;
}something;
直接从文件中读取将在m2和m3中放置错误的值,并读取额外的2个字节。
我已经四处闯荡,目前正在使用的是以下几项,效果很好:
typedef struct
{
uint16_t m1;
struct
{
uint16_t lo;
uint16_t hi;
}m2;
struct
{
uint16_t lo;
uint16_t hi;
}m3;
}something;
然而,这看起来像是一个非常肮脏的黑客。我忍不住希望有一个更干净的方法来强制编译器将m2和m3的一半放在不同的词中,不管它是次优的。
我正在使用arm none eabi gcc。我知道位包装,但无法围绕这个优化工作。
编辑:原来我对比特包装了解不够:D
最佳答案
您需要的是packed
属性。这将迫使gcc不在成员周围做任何填充。摘自GCC Online docs:
拥挤的
附加到枚举、结构或联合类型定义的此属性指定使用所需的最小内存来表示该类型。
为结构和联合类型指定此属性等同于在每个结构或联合成员上指定压缩属性。在行上指定-fshort enums标志等同于在所有枚举定义上指定压缩属性。
只能在枚举定义的右大括号后指定此属性,不能在typedef声明中指定,除非该声明还包含枚举的定义。
所以你想要的是:
typedef struct
{
uint16_t m1;
uint32_t m2;
uint32_t m3;
} __attribute__ ((packed)) something;
此外,我建议使用compile time assertion check来确保结构的大小是您真正想要的。
关于c - 如何重写C编译器将struct中的字长变量对准字边界,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30923228/