GNU C字节对齐__attribute__((aligned(n))) #pragma pack(n)
在阅读gnu软件c源代码时,经常会遇到字节对齐相关操作,比如uboot命令相关的代码中,会遇到__attribute__((aligned(n)))
扩展关键字,#pragma pack(n)
预处理指令,修饰变量或者类型后,会产生怎样的影响呢?
1. #pragma pack(n)
#pragma pack(n)
是一条预处理指令,告诉编译器结构体或类内部的成员变量相对于第一个变量的地址的偏移量的对齐方式,缺省情况下,编译器按照自然边界对齐,当变量所需的自然对齐边界比n大时,按照n对齐,否则按照自然边界对齐;使用#pragma pack()
取消指定对齐,恢复缺省对齐。
下面案例中,st结构体2字节对齐,结构体大小为4字节。
#pragma pack(8)
struct st
{
short f[2];
};
#pragma pack () /*取消指定对齐,恢复缺省对齐*/
下面案例中,st结构体2字节对齐,结构体大小为6字节。
#pragma pack(2)
struct st
{
char c;
int i;
};
#pragma pack () /*取消指定对齐,恢复缺省对齐*/
总结为下面2个结论:
1)作用对象:#pragma pack(n)
指定的是结构体成员的对齐边界;
2)对齐边界:alignment = min(n, max(member alignment))
2. __attribute__((aligned(n)))
2.1 修饰变量
int more_aligned_int __attribute__((aligned(8)));
int类型自然对齐边界是4字节对齐。指定对齐后,整型变量more_aligned_int将在内存中8字节边界对齐。
2.2 修饰结构体类型
2.2.1 语法格式
__attribute__(((aligned(n)))
修饰结构体,可以放在结构体struct关键字之后,或者类型定义最后一个花括号之后,分号之前。但是更推荐前一种,因为从逻辑上讲,花括号结束意味着类型定义的结束。(https://gcc.gnu.org/onlinedocs/gcc-11.2.0/gcc/Common-Type-Attributes.html#Common-Type-Attributes)
struct st
{
short f[2];
}__attribute__((aligned(8)));
2.2.2 对结构体变量对齐的影响
__attribute__((aligned(n)))
告诉编译器一个结构体或者类或者联合或者一个类型的变量(对象)分配地址空间时的地址对齐方式。
也就是说,如果将__attribute__((aligned(n)))
作用于一个类型,那么该类型的变量在分配地址空间时,其存放的地址一定按照n字节对齐(n必须是2的幂次方)。并且其占用的空间,即大小,也是n的整数倍,以保证在申请连续存储空间的时候,每一个元素的地址也是按照n字节对齐。
特殊的,当结构体成员中自然对齐边界最大值m大于n时,相应的对齐边界则为m,结构体大小也为m的整数倍。
struct st
{
short f[2];
}__attribute__((aligned(8)));
上面案例中,结构体大小为8字节,起始地址8字节对齐;
struct st
{
char c;
int i;
}__attribute__((aligned(2)));
上面案例中,结构体起始地址4字节对齐,结构体大小为4的整数倍,为8字节,注意不是6字节,因为结构体成员i为int类型,自然对齐边界为4,大于指定对齐边界2。
最后总结为下面4个结论:
1)关于作用对象:该类型定义的变量,而不是该类型的成员。成员按照自然边界对齐
2)关于对齐边界:alignment = max(n, max(member alignment))
3)关于起始地址:start_addr align to alignment
4)关于占用空间:var_size=N*alignment
本文作者:流云的博客
本文链接:https://www.cnblogs.com/arminker/p/15322746.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ThreeJs-16智慧城市项目(重磅以及未来发展ai)
· .NET 原生驾驭 AI 新基建实战系列(一):向量数据库的应用与畅想
· Ai满嘴顺口溜,想考研?浪费我几个小时
· Browser-use 详细介绍&使用文档
· 软件产品开发中常见的10个问题及处理方法