在阅读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

GNU C字节对齐__attribute__((aligned(n))) #pragma pack(n)的更多相关文章

  1. C语言字节对齐 __align(),__attribute((aligned (n))),#pragma pack(n)

    转载地址 : http://blog.csdn.net/21aspnet/article/details/6729724 一.概念    对齐跟数据在内存中的位置有关.如果一个变量的内存地址正好位于它 ...

  2. C语言字节对齐 __align(),__attribute((aligned (n))),#pragma pack(n)【转】

    转自:https://www.cnblogs.com/ransn/p/5081198.html 转载地址 : http://blog.csdn.net/21aspnet/article/details ...

  3. stm32中使用#pragma pack(非常有用的字节对齐用法说明)

    #pragma pack(4)   //按4字节对齐,但实际上由于结构体中单个成员的最大占用字节数为2字节,因此实际还是按2字节对齐 typedef struct { char buf[3];//bu ...

  4. 转载:C语言的字节对齐及#pragma pack的使用

    C语言的字节对齐及#pragma pack的使用   C编译器的缺省字节对齐方式(自然对界) 在缺省情况下,C编译器为每一个变量或是数据单元按其自然对界条件分配空间. 在结构中,编译器为结构的每个成员 ...

  5. 字节对齐#pragma pack

    这是给编译器用的参数设置,有关结构体字节对齐方式设置, #pragma pack是指定数据在内存中的对齐方式. #pragma pack (n)             作用:C编译器将按照n个字节对 ...

  6. C语言字节对齐

    转自:http://blog.csdn.net/21aspnet/article/details/6729724 文章最后本人做了一幅图,一看就明白了,这个问题网上讲的不少,但是都没有把问题说透. 一 ...

  7. C语言字节对齐问题详解

    引言 考虑下面的结构体定义: typedef struct{ char c1; short s; char c2; int i; }T_FOO; 假设这个结构体的成员在内存中是紧凑排列的,且c1的起始 ...

  8. C语言字节对齐问题详解(对齐、字节序、网络序等)

    首先说明一下,本文是转载自: http://www.cnblogs.com/clover-toeic/p/3853132.html 博客园用的少,不知道怎么发布转载文章,只能暂时这样了. 引言 考虑下 ...

  9. <摘录>字节对齐(强制对齐以及自然对齐)

    struct {}node; 32为的x86,window下VC下sizeof(node)的值为1,而linux的gcc下值为0: 一.WINDOWS下(VC--其实GCC和其原理基本一样,象这种问题 ...

随机推荐

  1. 一文掌握 Python 的描述符协议

    描述符介绍 描述符本质就是一个新式类,在这个新式类中,至少要实现了__get__(),__set__(),__delete__()中的一个.这也被称为描述符协议. class Myclass(obje ...

  2. ciscn_2019_es_1

    拿到题目例行检查 将题目放到idax64中进行代码审计 主界面,我也没看懂什么意思 call 可以看到free的指针没有置零,存在uaf漏洞 add函数 show函数 该题的libc版本是2.27,所 ...

  3. 数组队列如何手撕?解密ArrayBlockingQueue的实现内幕!

    队列 聊起队列,你一定会联想到一个与队列相似的数据结构:栈. 为了更好的理解什么是队列,我们将它和栈来比较一下: 队列的特点是:先进先出,如下图,1先进,1就先出. 图1:队列的图解 栈的特点是:先进 ...

  4. java File 类对操作系统文件目录进行操作:增删查

    File类 1,概述 File类是java.io包下代表与平台无关的文件和目录,也就是说,如果希望在程序中操作文件和目录,都可以通过File类来完成. 2,构造方法 public File(Strin ...

  5. SQL:利用多表更新优化子查询

    原SQL: update bi_data.order_list_wxset is_start='1',proc_time=now()where 1=1and is_end='0' and 交易时间&l ...

  6. JAVA工具类获取HttpServletRequest、HttpServletResponse 对象

    添加依赖 <!-- Spring Web --> <dependency> <groupId>org.springframework</groupId> ...

  7. nim_duilib(7)之TreeView

    introduction 更多控件用法,请参考 here 和 源码. 本文的代码基于这里 xml文件添加代码 基于上一篇, 继续向basic.xml中添加下面关于TreeView的代码. xml完整源 ...

  8. c++内存分布之纯虚函数

    关于 本文演示环境:VS2017+32位程序. 纯虚函数是一种特殊的虚函数.可以预测到:虚函数的结论同样适用纯虚函数,但是纯虚函数是一种特殊的存在,还是看看实际结果. 代码写的不够规范: 因为任何带虚 ...

  9. 【LeetCode】398. Random Pick Index 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 每次遍历索引 字典保存索引 蓄水池抽样 日期 题目地 ...

  10. DP? (hdu3944)

    DP? Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 128000/128000 K (Java/Others)Total Subm ...