ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

指定内存对齐

2021-08-20 18:00:21  阅读:210  来源: 互联网

标签:字节数 指定 编译器 内存 pragma 对齐 identifier pack


链接:https://www.jianshu.com/p/d994731f658d

#pragma pack()

1.#pragma简述:

在所有的预处理指令中,#Pragma 指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作。#pragma指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的情况下,给出主机或操作系统专有的特征。依据定义,编译指示是机器或操作系统专有的,且对于每个编译器都是不同的。 今天为大家说的就是其中的#pragma pack指令。

2.#pragma pack的作用:

这个其实点进这个帖子的人都懂,#pragma pack 的主要作用就是改变编译器的内存对齐方式,这个指令在网络报文的处理中有着重要的作用,#pragma pack(n)是他最基本的用法,其作用是改变编译器的对齐方式, 不使用这条指令的情况下,编译器默认采取#pragma pack(8)也就是8字节的默认对齐方式,n值可以取(124816) 中任意一值。

3.#pragma pack详细介绍:

想必大家也看烦了,那么下面我就开始为大家介绍#pragma pack的详细用法:

3.1 #pragma pack(show):

#pragma pack(show)显示当前内存对齐的字节数。也就是packing aligment
我们常说编译器默认8字节对齐我们怎么知道的呢?
如下图所示: 

 

在程序中#pragma pack(show)会在编译阶段提出一个警告,说明当前对齐字节数。

3.2 #pragma pack(push [, identifier] [, n])

单纯使用#pragma pack(push)会将当前的对齐字节数压入栈顶,并设置这个值为新的对齐字节数, 就是说不会改变这个值。
  而使用#pragma pack(push, n) 会将当前的对齐字节数压入栈顶,并设置n为新的对齐字节数。
  再就是这个#pragma pack(push, identifier [, n])会在上面的操作基础上为这个对齐字节数附上一个标识符, 这里注意这个标识符只能以($_字母)开始, 标识符中可以有($_字母数字),并且标识符不能是关键字(push, pop可以作为标识符)。这个标识符的作用我会在pop中详细介绍。
push的使用:

 

3.3 #pragma pack(pop [, identifier] [, n])

同样单纯使用#pragma pack(pop)会弹出栈顶对齐字节数,并设置其为新的内存对齐字节数。

 

使用#pragma pack(pop, n)情况就不同了, 他会弹出栈顶并直接丢弃,设置n为其新的内存对齐字节数。

 

#pragma pack(pop, identifier [, n])较为复杂,编译器执行这条执行时会从栈顶向下顺序查找匹配的identifier,找到identifier相同的这个数之后将从栈顶到identifier,包括找到identifier全部pop弹出, 若没有找到则不进行任何操作。

 

由于前面提到的pushpop也可以作为关键字所以可以设计出很有戏剧效果的预处理头:

 

#pragma pack一系列的预处理指令在网络报文构造中有着重要的应用,是编译器处理内存的重要指令,同时我也希望各位面试官注意自身知识体系,不要再自己一知半解的情况下乱问问题,我会在下次写一篇关于C++内存对齐的详细介绍敬请期待!

以上是原博客内容

下面是我遇到的一点情况(见注释):

#pragma pack(show)//默认内存对其按照8个字节,==8
#pragma pack(4)//将8个字节对齐改成了4个字节
#pragma pack(show)//==4
typedef struct
{
    uint32_t iDeviceType;                          // see above defines
    char     szPath[512];                          // device path to use in FZ_Open
    char     szShortName[32];                      // a more user friendly name
    char     szSerial[16];                         // device serial number
    uint32_t iReserved[64];
} FZ_DEVICE_INFO;
#pragma pack(show)//==4,没有发生改变
#pragma pack()//将内存对齐设置变成默认的8个字节
#pragma pack(show)//==8

 

标签:字节数,指定,编译器,内存,pragma,对齐,identifier,pack
来源: https://www.cnblogs.com/yifengs/p/15167554.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有