跳至内容

C 结构体布局

字段偏移、填充、总大小与 C99 校验。

正在准备工具…

对齐规则

结构体字段按类型对齐,字段之间和结构体末尾可能插入填充:

offseti=alignUp⁡(offseti−1+sizei−1, aligni) \mathrm{offset}_{i}=\operatorname{alignUp}\left(\mathrm{offset}_{i-1}+\mathrm{size}_{i-1},\ \mathrm{align}_i\right)

总大小向上对齐到结构体的最大成员对齐。packed 把成员对齐降为 1,字段之间不再自动填充,但可能产生未对齐访问。

ARM AAPCS32 下,uint8_t cmd; uint32_t value; uint16_t crc; 的偏移为 0、4、8,总大小为 12;packed 后偏移为 0、1、5,总大小为 7。x86-64 对这三个类型的结果相同。

ABI 差异

C 标准不规定 int、long、指针和 double 的宽度,页面按所选 ABI 使用固定表。x86-64 Windows 使用 LLP64,long 仍是 4 字节;ARM、RISC-V 和 AVR 的 long、指针和浮点对齐各不相同。跨 MCU 与 PC 传输结构体时,先固定字段宽度,再核对偏移。

头文件为每个字段生成 offsetof 校验,并用 C99 负数组宏做编译期断言。结构体只支持标量和数组,不支持位域、嵌套结构体和联合体;位域布局由编译器实现定义,不用这套规则推断。

边界

字段名必须是 C 标识符,数组长度限制 1–1024,总大小上限由页面校验。末尾填充单独显示,不并进最后一个字段。ABI 名称只描述常见调用约定,编译器选项和板级支持包仍可能改变结果。