#pragma pack可以用來指定C++數據結構的成員變量的內存對齊數值(可選值為1,2,4,8,16)。
本文主要是強調在你的頭文件中使用pack指令要配對使用,以避免意外影響項目中其他源文件的結構成員的內存對齊。
如果影響了其他源文件的結構成員內存對齊,那麼在你按照默認對齊來計算那些結構成員占用內存大小
或者使用指針移動計算結構成員偏移位置的時候,就可能會出現意料之外的異常。
主要可能的異常是內存定位錯誤或非法內存訪問,結果可能導致錯誤的定位或數值,極端的情況下可能導致程序崩潰。
下面的例子用來展示基本的配對使用方式。
1)#pragma pack(n)的配對使用
//filename: header1.h #pragma pack(1) //內存對齊設置為1個字節
struct s1 { int i; char c; bool f; } //struct s2{...} //... #pragma pack() //恢復默認的內存對齊(與文件開頭的指令配對使用)
2)#pragma pack(push|pop,n)的配對使用
//filename: header2.h #pragma pack(push,1) //內存對齊設置為1個字節 struct s3 { int i; char c; bool f; } //struct s4{...} //... #pragma pack(pop) //恢復默認的內存對齊(與文件開頭的指令配對使用)
MSDN上VC++2013的幫助文檔關於pack指令的用法說明如下,供參考。
-------------------- 以下摘自MSDN ----------------------------
#pragma pack( [ n] )Specifies packing alignment for structure and union members. Whereas the packing alignment of structures and unions is set for an entire translation unit by the /Zp option, the packing alignment is set at the data-declaration level by the pack pragma. The pragma takes effect at the first structure or union declaration after the pragma is seen; the pragma has no effect on definitions.
When you use #pragma pack(n), where n is 1, 2, 4, 8, or 16, each structure member after the first is stored on the smaller member type or n-byte boundaries. If you use#pragma pack without an argument, structure members are packed to the value specified by /Zp. The default /Zp packing size is /Zp8.
The compiler also supports the following enhanced syntax:
#pragma pack( [ [ { push | pop}, ] [ identifier, ] ] [ n ] )
This syntax allows you to combine program components into a single translation unit if the different components use pack pragmas to specify different packing alignments.
Each occurrence of a pack pragma with a push argument stores the current packing alignment on an internal compiler stack. The pragma’s argument list is read from left to right. If you use push, the current packing value is stored. If you provide a value for n, that value becomes the new packing value. If you specify an identifier, a name of your choosing, the identifier is associated with the new packing value.
Each occurrence of a pack pragma with a pop argument retrieves the value at the top of an internal compiler stack and makes that value the new packing alignment. If you use pop and the internal compiler stack is empty, the alignment value is that set from the command-line and a warning is issued. If you use pop and specify a value for n, that value becomes the new packing value. If you use pop and specify an identifier, all values stored on the stack are removed from the stack until a matchingidentifier is found. The packing value associated with the identifier is also removed from the stack and the packing value that existed just before the identifier was pushed becomes the new packing value. If no matching identifier is found, the packing value set from the command line is used and a level-one warning is issued. The default packing alignment is 8.