You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用__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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 01:27:33