天天看點

#pragma pack

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)     // 1

#pragma pack(pop, 8)   // 彈出編譯棧棧頂的 2 , 然後丢棄, 再将目前對齊值設為 8 .

#pragma pack(pop, 1)   // 彈出編譯棧棧頂的 4 , 然後丢棄, 再将目前對齊值設為 1 .

#pragma pack(pop, 2)   // 彈出編譯棧棧頂的 16 , 然後丢棄, 再将目前對齊值設為 2 .

#pragma pack(pop, 16)  // 彈出編譯棧棧頂的 8 , 然後丢棄, 再将目前對齊值設為 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(pop, identifier_6)      // 将辨別符 identifier_6 對應的棧中值 16 彈出, 并将其設為目前對齊值.

#pragma pack(pop, identifier_5, 2)   // 将辨別符 identifier_6 對應的棧中值 8 彈出, 然後丢棄, 再将目前對齊值設為 2 .

#pragma pack(pop, identifier_1)      // 按入棧順序進行彈出, 直到遇到辨別符 identifier_1 辨別的8 .

繼續閱讀