美文网首页
【转】关于#pragma pack

【转】关于#pragma pack

作者: kim4apple | 来源:发表于2018-06-27 18:02 被阅读8次

pack 为 struct, union 和 class 等的成员对齐指定字节边界. 与编译选项的 /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)                   // 16
#pragma pack(push, identifier_6)     // 上上句 16 压入编译栈栈顶, 并将栈中 16 对应的位置用 identifier_6 标识起来.
#pragma pack(show)                   // 16
#pragma pack(pop, identifier_6)      // 将标识符 identifier_6 对应的栈中值 16 弹出, 并将其设为当前对齐值.
#pragma pack(show)                   // 16
#pragma pack(pop, identifier_5, 2)   // 将标识符 identifier_6 对应的栈中值 8 弹出, 然后丢弃, 再将当前对齐值设为 2 .
#pragma pack(show)                   // 2
#pragma pack(pop, identifier_1)      // 按入栈顺序进行弹出, 直到遇到标识符 identifier_1 标识的8 .
#pragma pack(show)                   // 8

相关文章

  • 【转】关于#pragma pack

    pack 为 struct, union 和 class 等的成员对齐指定字节边界. 与编译选项的 /Zp 开关不...

  • #pragma pack()

    计算机中内存空间都是按照byte划分的从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特...

  • iOS 一字节对齐

    一字节对齐的写法 #pragma pack(1) 结构体 #pragma pack() __attribute__...

  • 【嵌入式C】在Keil中结构体的字节对齐

    使用关键字#pragma pack (1)开始字节对齐,使用#pragma pack ()结束。 比如: 这样做的...

  • 结构体对齐方式

    #pragma pack()用法详解

  • #pragma pack()用法

    在阅读代码特别是C语法代码的过程中,其实经常会遇到#pragma pack(n),#pragma pack(),#...

  • 关于预处理指令#pragma pack

    简单理解#pragma 作为较为复杂的预处理指令之一,它的作用为更改编译器的编译状态以及为特定的编译器提供特定的编...

  • #pragma pack 指令详解!

    1.#pragma简述: 在所有的预处理指令中,#Pragma 指令可能是最复杂的了,它的作用是设定编译器的状态或...

  • #pragma pack(push,1)与#pragma pac

    这是给编译器用的参数设置,有关结构体字节对齐方式设置, #pragma pack是指定数据在内存中的对齐方式。 #...

  • C_language_renew07

    结构体大小结构体对齐原则: x86(linux 默认#pragma pack(4),window默认#pragma...

网友评论

      本文标题:【转】关于#pragma pack

      本文链接:https://www.haomeiwen.com/subject/jdjiyftx.html