pack
pragma
指定結構、等位和類別成員的封裝對齊方式。
語法
#pragma pack( show )
#pragma pack( push
[,
] [ ] [,
n
]identifier
)
#pragma pack( pop
[,
{identifier
|n
} ])
#pragma pack(
[n
])
參數
show
(選擇性)顯示封裝對齊的目前位元組值。 此值是透過警告訊息顯示。
push
(選擇性)將內部編譯程式堆疊上的目前封裝對齊值推送,並將目前的封裝對齊值設定為 n。 如果未 指定 n ,則會推送目前的封裝對齊值。
pop
(選擇性)從內部編譯程式堆疊頂端移除記錄。 如果未使用 pop
指定 n,則與堆疊頂端產生的記錄相關聯的封裝值是新的封裝對齊值。 如果指定 n,例如 ,#pragma pack(pop, 16)
n 會變成新的封裝對齊值。 例如,#pragma pack(pop, r1)
如果您使用 彈出 identifier
,則堆疊上的所有記錄都會彈出,直到找到的identifier
記錄為止。 該記錄會快顯,且與堆疊頂端找到之記錄相關聯的封裝值會變成新的封裝對齊值。 如果您使用堆疊上任何紀錄中找不到的 彈出視窗 identifier
, pop
則會忽略 。
語句 #pragma pack (pop, r1, 2)
相當於 #pragma pack (pop, r1)
後面 #pragma pack(2)
接著 。
identifier
(選擇性)搭配 push
使用 時,會將名稱指派給內部編譯程式堆疊上的記錄。 搭配 pop
使用 時,會從內部堆疊取出記錄,直到 identifier
移除為止。 如果在 identifier
內部堆疊上找不到 ,則不會彈出任何專案。
n
(選擇性)指定要用於封裝的值,以位元組為單位。 如果未為模組設定編譯程序選項 /Zp
,則的 n
預設值為8。 有效值為 1、2、4、8 和 16。 成員的對齊方式位於的界限上,可以是的倍 n
數,或是成員大小的倍數,無論大小較小。
備註
封裝類別是將其成員直接放在記憶體中。 這表示部分或所有成員可以在小於目標架構默認對齊的界限上對齊。 pack
提供數據宣告層級的控制件。 它與編譯程式選項 /Zp
不同,它只提供模組層級控件。 pack 會在 看到 之後的第一個 struct
、 union
或 class
宣告生效 pragma 。 pack
對定義沒有任何影響。 在沒有自變數的呼叫 pack
時,會將 設定 n
為編譯程式選項 /Zp
中設定的值。 如果未設定編譯程式選項,則 x86、ARM 和 ARM64 的預設值為 8。 x64 原生和ARM64EC的預設值為16。
如果您變更 結構的對齊方式,它可能不會在記憶體中使用太多空間。 不過,您可能會看到效能遺失,甚至收到硬體產生的例外狀況,以進行未對齊的存取。 您可以使用 來修改此例外狀況行為 SetErrorMode
。
如需如何修改對齊方式的詳細資訊,請參閱下列文章:
-
警告
在 Visual Studio 2015 和更新版本中,您可以使用標準和
alignas
alignof
運算符,這與編譯程式不同__alignof
且__declspec( align )
可移植。 C++標準無法處理封裝,因此您仍pack
必須使用 (或其他編譯程式上的對應延伸模組) 來指定小於目標架構字型大小的對齊方式。
範例
下列範例示範如何使用 pack
pragma 來變更 結構的對齊方式。
// pragma_directives_pack.cpp
#include <stddef.h>
#include <stdio.h>
struct S {
int i; // size 4
short j; // size 2
double k; // size 8
};
#pragma pack(2)
struct T {
int i;
short j;
double k;
};
int main() {
printf("%zu ", offsetof(S, i));
printf("%zu ", offsetof(S, j));
printf("%zu\n", offsetof(S, k));
printf("%zu ", offsetof(T, i));
printf("%zu ", offsetof(T, j));
printf("%zu\n", offsetof(T, k));
}
0 4 8
0 4 6
下列範例示範如何使用 推送、 快顯和 顯示 語法。
// pragma_directives_pack_2.cpp
// compile with: /W1 /c
#pragma pack() // n defaults to 8; equivalent to /Zp8
#pragma pack(show) // C4810
#pragma pack(4) // n = 4
#pragma pack(show) // C4810
#pragma pack(push, r1, 16) // n = 16, pushed to stack
#pragma pack(show) // C4810
// pop to the identifier and then set
// the value of the current packing alignment:
#pragma pack(pop, r1, 2) // n = 2 , stack popped
#pragma pack(show) // C4810