在阅读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. 有个性的手动计划模式(Project)

    <Project2016 企业项目管理实践>张会斌 董方好 编著 任务工作表里默认的标题"工期"."开始时间"."结束时间"这些 ...

  2. Spring5 AOP编程:关于org.springframework.beans.factory.BeanNotOfRequiredTypeException报错

    Spring5 AOP编程:关于org.springframework.beans.factory.BeanNotOfRequiredTypeException报错 先上错误详细信息: org.spr ...

  3. CF74A Room Leader 题解

    Content 一场 CF 比赛有 \(n\) 个人,有 ABCDE 五道题目.在比赛过程中,参赛者还可以随时互相攻击,成功一次加 \(100\) 分,失败一次扣 \(50\)分,已知第 \(i\) ...

  4. CF792A New Bus Route 题解

    Content 给定一个长度为 \(n\) 的数列 \(a_1,a_2,a_3,...,a_n\),求这个序列当中差的绝对值最小的数对并求出这样的数对的个数. 数据范围:\(2\leqslant n\ ...

  5. signal 信号

    python学习笔记--信号模块signal 阅读目录(Content) 1 signal基本信号名 2 常用信号处理函数 2.1 设置发送SIGALRM信号的定时器 2.2 设置信号处理函数 3 常 ...

  6. X-Tim开发日志

    1.X-Tim--------一个极客风的手表 引言 很久之前就看到FASTSHIFT,但是水平太差,可是又想做一个这样的手表,于是在学习了FASTSHIFT的页面管理之后,也开始了X-Tim的制作. ...

  7. django——django链接mysql数据库

    1.创建项目 django-admin startproject django_mysql 2.创建App python manage.py startapp app1 3.Mysql数据库配置 (1 ...

  8. C++之递归遍历数组

    倒序输出 源码 void print_arr_desc(int arr[], unsigned int len) { if (len) { std::cout << "a[&qu ...

  9. fedora之自动寻找命令并提示安装PackageKit-command-not-found

    fedora 1.比如,我要用clang 命令编译代码,但是没有该指令.比如: clang main.cxx -o main 2.那么,输入未知命令,希望fedora会自动寻找相对应的包,再并提示安装 ...

  10. 【九度OJ】题目1181:遍历链表 解题报告

    [九度OJ]题目1181:遍历链表 解题报告 标签(空格分隔): 九度OJ http://ac.jobdu.com/problem.php?pid=1181 题目描述: 建立一个升序链表并遍历输出. ...