使用__unaligned与packed属性的C结构体在线编译报错求助
解决ARM专属结构体扩展在标准编译器的编译问题
问题原因
你代码里的__unaligned是ARM编译器(ARMCC)专属的非标准关键字,用于标记非对齐内存访问;而__attribute__((packed))虽被GCC/Clang支持,但__unaligned是ARM独有的,在线编译器(通常基于GCC、Clang或标准C实现)不识别这个关键字,因此编译失败。Keil使用的ARMCC编译器支持这些扩展,所以能正常运行。
解决方案
根据你的需求,提供几种兼容方案:
1. 跨ARM编译器与标准编译器的兼容写法
通过预定义宏区分编译器,仅在ARMCC环境下保留__unaligned关键字:
#include <stdio.h> #ifdef __ARMCC_VERSION__ typedef __unaligned struct __attribute__((packed)) { #else typedef struct __attribute__((packed)) { #endif int a; int b; } a_b; int main() { printf("%d", sizeof(a_b)); return 0; }
__ARMCC_VERSION__是ARM编译器的内置宏,仅Keil等ARMCC环境会定义,此时保留__unaligned;- 其他编译器会跳过
__unaligned,仅使用__attribute__((packed))保证结构体无填充,同时保持代码可编译。
2. 适配标准编译器的简化写法
如果仅需要在在线编译器测试结构体打包后的大小,直接去掉ARM专属的__unaligned关键字即可,GCC/Clang支持__attribute__((packed)):
#include <stdio.h> typedef struct __attribute__((packed)) { int a; int b; } a_b; int main() { printf("%d", sizeof(a_b)); return 0; }
这种写法编译后,结构体大小和ARM环境下一致(均为8字节,无填充字节),满足你测试结构体大小差异的需求。
3. 纯标准C兼容写法(无编译器扩展)
如果需要完全符合C标准,不依赖任何编译器扩展,可以手动用字节数组模拟打包结构,但使用时需要手动转换数据:
#include <stdio.h> #include <string.h> typedef struct { unsigned char data[8]; // 两个int的总字节数(假设int为4字节) } a_b; int get_a(a_b *obj) { int val; memcpy(&val, obj->data, sizeof(int)); return val; } void set_a(a_b *obj, int val) { memcpy(obj->data, &val, sizeof(int)); } int main() { printf("%d", sizeof(a_b)); return 0; }
这种写法能在所有标准C编译器运行,但操作结构体成员需要手动内存拷贝,使用成本较高,适合必须严格遵循标准的场景。
内容的提问来源于stack exchange,提问作者vii_vii
相关产品推荐
相关产品推荐

