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

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:属性作用于结构体类型

    1. packed属性让结构体成员紧凑排列,内部无填充字节,3个uint8_t(共3字节)加1个uint32_t(4字节),成员总长度是7字节。
    2. aligned(4)作用在类型上时,不仅要求该类型的变量首地址按4字节对齐,还会在结构体末尾追加填充字节,让整个结构体的大小成为对齐值的整数倍。这是因为如果用该结构体定义数组,数组中每个元素的首地址都需要满足对齐要求,所以结构体本身的大小必须是对齐边界的倍数。7字节向上取整到最近的4的倍数就是8字节,所以sizeof(pkt1)结果为8。
  • pkt2:属性作用于单个变量

    1. struct packet_v2仅加了packed属性,所以结构体内部无填充,大小固定为7字节。
    2. aligned(4)只作用在变量pkt2上,仅要求这个变量的首地址按4字节对齐,但不会修改结构体类型本身的大小——它只是改变了这个变量在内存中的存储位置,确保起始地址符合对齐要求,结构体的大小依然是紧凑后的7字节。

简单来说:给类型加aligned会同时约束首地址对齐和结构体大小为对齐倍数;给变量加aligned只约束该变量的首地址对齐,不改变结构体本身的大小。

内容的提问来源于stack exchange,提问作者Typeof undefined

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 13:10:09