• 正文
  • 相关推荐
申请入驻 产业图谱

结构体对齐与压缩对齐操作

05/05 10:25
301
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

先看一组测试代码:

#include “stdio.h”
typedef struct {    unsigned char   a;    float           b;    unsigned short  c;    int             d;}para_t;
typedef struct {    unsigned char   a;    float           b;    unsigned short  c;    int             d;}__attribute__((packed)) para_packed_t;
int main(void){    printf("c test start,build at %s,%srn",__DATE__,__TIME__);
    printf(""unsigned char " size is %drn",sizeof(unsigned char));    printf(""float         " size is %drn",sizeof(float));    printf(""unsigned short" size is %drn",sizeof(unsigned short));    printf(""int           " size is %drn",sizeof(int));
    para_t para;
    printf("para size is  %drn",sizeof(para_t));
    printf("para member "a" index is %d,address is 0x%xrn",offsetof(para_t,a),&para.a);    printf("para member "b" index is %d,address is 0x%xrn",offsetof(para_t,b),&para.b);    printf("para member "c" index is %d,address is 0x%xrn",offsetof(para_t,c),&para.c);    printf("para member "d" index is %d,address is 0x%xrn",offsetof(para_t,d),&para.d);
    para_packed_t para_packed;
    printf("para_packed size is  %drn",sizeof(para_packed_t));
    printf("para_packed member "a" index is %d,address is 0x%xrn",offsetof(para_packed_t,a),&para_packed.a);    printf("para_packed member "b" index is %d,address is 0x%xrn",offsetof(para_packed_t,b),&para_packed.b);    printf("para_packed member "c" index is %d,address is 0x%xrn",offsetof(para_packed_t,c),&para_packed.c);    printf("para_packed member "d" index is %d,address is 0x%xrn",offsetof(para_packed_t,d),&para_packed.d);
    printf("c test end!rn");
    return 0;}
执行后,结果如下:
"unsigned char " size is 1"float         " size is 4"unsigned short" size is 2"int           " size is 4para size is  16para member "a" index is 0,address is 0x61fe40para member "b" index is 4,address is 0x61fe44para member "c" index is 8,address is 0x61fe48para member "d" index is 12,address is 0x61fe4cpara_packed size is  11para_packed member "a" index is 0,address is 0x61fe35para_packed member "b" index is 1,address is 0x61fe36para_packed member "c" index is 5,address is 0x61fe3apara_packed member "d" index is 7,address is 0x61fe3c

可以看出对于 typedef struct { ...} para_t编译器自动对齐,在成员a之后填充了3个字节,在成员c之后填充了2个字节,最终得到整个结构体是16字节,且每个成员的地址都是4的倍数;

对于typedef struct {...}__attribute__((packed)) para_packed_t,加了取消对齐的操作,也可以叫做1字节对齐,成员之间没有填充,最终得到整个结构体是11字节,成员的地址不全是4的倍数。

加了packed的作用:

结构体占用空间最小,不浪费空间,对嵌入式数据存储通信协议封装、硬件寄存器等非常适用,但是也会带来一个问题,非对齐访问,会导致CPU访问速度变慢,对不支持非对齐访问的硬件会导致hardfault异常。

对于不同平台,取消编译器对齐的写法不一样:

GCC:__attribute__((packed))

MDK:__packed

扩展:

除了编译器根据最大成员默认对齐以外,我们还可以使用__attribute__((aligned(n)))指定对齐数,这里n可以取为4,8,16等。

Cortex-m0、C2000不支持非对齐访问,Cortex-m3、m4支持非对齐访问。

——————END——————

相关推荐

登录即可解锁
  • 海量技术文章
  • 设计资源下载
  • 产业链客户资源
  • 写文章/发需求
立即登录

公众号:物联网思考;主要记录、分享、思考开发中遇到的技术小细节,涉及嵌入式单片机、C语言、传感器、低功耗物联网等。偶尔也可能是程序员健康、职场潜规则、生活思考、行业讨论。