#pragma pack 用法详解

转载 2012年03月30日 14:14:10

pack 为 struct, union 和 class 等的成员对齐指定字节边界. 与编译选项(属性 -> 配置属性 -> C/C++ ->代码生成 -> 结构成员对齐)的 /Zp 开关不同, 它不针对整个项目, 而仅针对模块, 比如一个编译单元.

1. #pragma pack(show)
以警告信息的形式显示当前字节对齐的值.
2. #pragma pack(n)
将当前字节对齐值设为 n .
3. #pragma pack()
将当前字节对齐值设为默认值(通常是8) .
4. #pragma pack(push)
将当前字节对齐值压入编译栈栈顶.
5. #pragma pack(pop)
将编译栈栈顶的字节对齐值弹出并设为当前值.
6. #pragma pack(push, n)
先将当前字节对齐值压入编译栈栈顶, 然后再将 n 设为当前值.
7. #pragma pack(pop, n)
将编译栈栈顶的字节对齐值弹出, 然后丢弃, 再将 n 设为当前值.
8. #pragma pack(push, identifier)
将当前字节对齐值压入编译栈栈顶, 然后将栈中保存该值的位置标识为 identifier .
9. #pragma pack(pop, identifier)
将编译栈栈中标识为 identifier 位置的值弹出, 并将其设为当前值. 注意, 如果栈中所标识的位置之上还有值, 那会先被弹出并丢弃.
10. #pragma pack(push, identifier, n)
将当前字节对齐值压入编译栈栈顶, 然后将栈中保存该值的位置标识为 identifier, 再将 n 设为当前值.
11. #pragma pack(pop, identifier, n)
将编译栈栈中标识为 identifier 位置的值弹出, 然后丢弃, 再将 n 设为当前值. 注意, 如果栈中所标识的位置之上还有值, 那会先被弹出并丢弃.

注意: 如果在栈中没有找到 pop 中的标识符, 则编译器忽略该指令, 而且不会弹出任何值.

// 代码段 1: 弹出编译栈的顺序跟压入的顺序相反
#pragma pack(show) // 8 (默认值)
#pragma pack(push, 16) // 默认值 8 压入编译栈栈顶, 并将当前对齐值设为 16 .
#pragma pack(show) // 上句设定的 16
#pragma pack(push, 4) // 上上句 16 压入编译栈栈顶, 并将当前对齐值设为 4 .
#pragma pack(show) // 上句设定的 4
#pragma pack(push, 2) // 上上句 4 压入编译栈栈顶, 并将当前对齐值设为 2 .
#pragma pack(show) // 上句设定的 2
#pragma pack(push, 1) // 上上句 2 压入编译栈栈顶, 并将当前对齐值设为 1 .
#pragma pack(show) // 上句设定的 1
#pragma pack(pop) // 弹出编译栈栈顶的 2 , 并将其设为当前对齐值.
#pragma pack(show) // 2
#pragma pack(pop) // 弹出编译栈栈顶的 4 , 并将其设为当前对齐值.
#pragma pack(show) // 4
#pragma pack(pop) // 弹出编译栈栈顶的 16 , 并将其设为当前对齐值.
#pragma pack(show) // 16
#pragma pack(pop) // 弹出编译栈栈顶的 8 , 并将其设为当前对齐值.
#pragma pack(show) // 8

// 代码段 2: pop 带有参数 n 时, 当前字节对齐值被设为了 n, 而不是从栈顶弹出的之前所压入的值.
#pragma pack(show) // 8 (默认值)
#pragma pack(push, 16) // 默认值 8 压入编译栈栈顶, 并将当前对齐值设为 16 .
#pragma pack(show) // 16
#pragma pack(push, 4) // 上上句 16 压入编译栈栈顶, 并将当前对齐值设为 4 .
#pragma pack(show) // 4
#pragma pack(push, 2) // 上上句 4 压入编译栈栈顶, 并将当前对齐值设为 2 .
#pragma pack(show) // 2
#pragma pack(push, 1) // 上上句 2 压入编译栈栈顶, 并将当前对齐值设为 1 .
#pragma pack(show) // 1
#pragma pack(pop, 8) // 弹出编译栈栈顶的 2 , 然后丢弃, 再将当前对齐值设为 8 .
#pragma pack(show) // 8
#pragma pack(pop, 1) // 弹出编译栈栈顶的 4 , 然后丢弃, 再将当前对齐值设为 1 .
#pragma pack(show) // 1
#pragma pack(pop, 2) // 弹出编译栈栈顶的 16 , 然后丢弃, 再将当前对齐值设为 2 .
#pragma pack(show) // 2
#pragma pack(pop, 16) // 弹出编译栈栈顶的 8 , 然后丢弃, 再将当前对齐值设为 16 .
#pragma pack(show) // 16

// 代码段3: push 和 pop 可以带有标识符, 此标识符能够弹出指定值. 但是, 位于栈中指定值之上的那些值均会被弹出并丢弃.
#pragma pack(show) // 8 (默认值)
#pragma pack(push, identifier_1, 1) // 默认值 8 压入编译栈栈顶, 并将栈中 8 对应的位置用 identifier_1 标识起来, 然后将当前对齐值设为 1 .
#pragma pack(show) // 1
#pragma pack(push, identifier_2, 2) // 上上句 1 压入编译栈栈顶, 并将栈中 1 对应的位置用 identifier_2 标识起来, 然后将当前对齐值设为 2 .
#pragma pack(show) // 2
#pragma pack(push, identifier_3, 4) // 上上句 2 压入编译栈栈顶, 并将栈中 2 对应的位置用 identifier_3 标识起来, 然后将当前对齐值设为 4 .
#pragma pack(show) // 4
#pragma pack(push, identifier_4, 8) // 上上句 4 压入编译栈栈顶, 并将栈中 4 对应的位置用 identifier_4 标识起来, 然后将当前对齐值设为 8 .
#pragma pack(show) // 8
#pragma pack(push, identifier_5, 16) // 上上句 8 压入编译栈栈顶, 并将栈中 8 对应的位置用 identifier_5 标识起来, 然后将当前对齐值设为 16 .
#pragma pack(show)

C++中#pragma pack(N)的用法

在32位机器上,下列代码中#pragma pack(2)class A { int i; union U { char buff[13]; int i...
  • zx3517288
  • zx3517288
  • 2016年10月17日 17:52
  • 973

GCC 对 #pragma pack(N)和__attribute__((packed)) 的支持问题

GCC 对 #pragma pack(N) 的支持问题  #pragma pack 这里重点讨论内存对齐的问题和#pragma pack()的使用方法。 什么是内存对齐? 先看下面的结构:...
  • yi412
  • yi412
  • 2015年06月30日 16:04
  • 2106

#pragma pack()用法详解

1.什么是对齐?为什么要对齐? 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问,这就需要各...
  • lime1991
  • lime1991
  • 2015年03月22日 11:20
  • 2530

#pragma pack([n|push|pop]) 用法

#pragma pack(): 取消用户自定义的结构体成员(或类的数据成员)的对齐方式,恢复编译器默认的对齐方式(VC++和GCC编译器默认8个字节对齐,并且,我们可以在编译器的设置里更改编译器的默...
  • crazywdy
  • crazywdy
  • 2014年06月23日 14:15
  • 3846

#Pragma Pack(n)与内存分配 pragma pack(push,1)与#pragma pack(1)的区别

from:http://blog.csdn.net/mylinx/article/details/7007309  #pragma pack(n) 解释一: 每个特定平台上的...
  • aidem_brown
  • aidem_brown
  • 2017年08月24日 20:20
  • 949

#pragma pack(1) 单身狗,自己挖坑自己踩

一些头文件里涉及网络传输的结构体被pack(1),pack()包裹的,然而有部分我新增的功能是从原有代码复制改写的,有一处只有pack,前面没有对应的pack(1),这倒问题不大,另一处是只有pack...
  • Bill_Xiang
  • Bill_Xiang
  • 2017年03月13日 22:44
  • 863

记录#pragma pack()的问题

在Cortex M0平台上做开发的时候,遇到一个纠结了两三天的问题。 代码添加了PWM马达控制后,继续做USB复合设备。在做好USB复合设备,发现原来的PWM马达控制不起作用了,首先对比了模块的寄存...
  • dndxhej
  • dndxhej
  • 2014年01月28日 17:56
  • 8928

#pragma pack 用法详解

pack 为 struct, union 和 class 等的成员对齐指定字节边界. 与编译选项(属性 -> 配置属性 -> C/C++ ->代码生成 -> 结构成员对齐)的 /Zp 开关不同, 它不...
  • sunnylion1982
  • sunnylion1982
  • 2014年07月21日 14:54
  • 364

Pragma的几种常用用法

Pragma的几种常用用法 其格式一般为: #Pragma Para 其中Para 为参数,下面来看一些常用的参数。 (1)message 参数。 Message 它能够在编译信息输出窗口中...
  • nodeman
  • nodeman
  • 2015年01月05日 13:52
  • 699

在#pragma pack(4)和#pragma pack(8)的情况下,结构体的大小分别是

下面两个结构体 struct One{     double d;     char c;     int i; } struct Two{     char c;     doub...
  • chengonghao
  • chengonghao
  • 2016年08月09日 10:46
  • 2092
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:#pragma pack 用法详解
举报原因:
原因补充:

(最多只允许输入30个字)