C语言中结构体的__attribute__((aligned(4), packed))使用疑问
结构体对齐属性位置差异导致大小不同的疑问
我需要用结构体存储数据并通过DMA传输,外设要求结构体首地址按4字节边界对齐。但我不理解为什么在不同位置使用aligned属性,会让紧凑(packed)结构体的大小相差1字节。以下是测试代码:
#include <stdio.h> #include "stdint.h" // 给结构体类型添加aligned属性的版本 struct packet_v1 { uint8_t uid; uint8_t flag; uint8_t comm; uint32_t a; } __attribute__((packed, aligned(4))); // 仅添加packed属性的结构体类型 struct packet_v2 { uint8_t uid; uint8_t flag; uint8_t comm; uint32_t a; } __attribute__((packed)); struct packet_v1 pkt1; struct packet_v2 pkt2 __attribute__((aligned(4))); int main() { printf("Align v1: %lu, size: %lu\r\n", (uintptr_t)&pkt1 % 4, sizeof(pkt1)); printf("Align v2: %lu, size: %lu\r\n", (uintptr_t)&pkt2 % 4, sizeof(pkt2)); return 0; }
程序输出:
Align v1: 0, size: 8 Align v2: 0, size: 7
问题解释
两者的核心区别在于aligned(4)属性的作用对象不同:
struct packet_v1:属性作用于结构体类型packed属性让结构体成员紧凑排列,内部无填充字节,3个uint8_t(共3字节)加1个uint32_t(4字节),成员总长度是7字节。aligned(4)作用在类型上时,不仅要求该类型的变量首地址按4字节对齐,还会在结构体末尾追加填充字节,让整个结构体的大小成为对齐值的整数倍。这是因为如果用该结构体定义数组,数组中每个元素的首地址都需要满足对齐要求,所以结构体本身的大小必须是对齐边界的倍数。7字节向上取整到最近的4的倍数就是8字节,所以sizeof(pkt1)结果为8。
pkt2:属性作用于单个变量struct packet_v2仅加了packed属性,所以结构体内部无填充,大小固定为7字节。aligned(4)只作用在变量pkt2上,仅要求这个变量的首地址按4字节对齐,但不会修改结构体类型本身的大小——它只是改变了这个变量在内存中的存储位置,确保起始地址符合对齐要求,结构体的大小依然是紧凑后的7字节。
简单来说:给类型加aligned会同时约束首地址对齐和结构体大小为对齐倍数;给变量加aligned只约束该变量的首地址对齐,不改变结构体本身的大小。
内容的提问来源于stack exchange,提问作者Typeof undefined
相关产品推荐
相关产品推荐

