#pragma pack()用法

在閱讀代碼特別是C語法代碼的過程中,其實經(jīng)常會遇到#pragma pack(n),#pragma pack(),#pragma pack(pack,n),#pragma pack(pop,n)等,其中n是可以省略的。
并且這些語句一般出現(xiàn)在結(jié)構(gòu)體前面。我們一般都知道該語句是用來進行內(nèi)存對齊的,但是總結(jié)得不是特別清晰。
我在查閱博客的過程中,找到了一個總結(jié)得比較好的帖子,然后補充一點我自己的情況。

以下是原博客內(nèi)容(#pragma pack 指令詳解!):

#pragma pack這個指令和他涉及的c/c++內(nèi)存對齊機制可能是技術(shù)開發(fā)類筆試面試被問道的最頻繁的問題之一了
,可惜筆者在實際生活中發(fā)現(xiàn)大量的工程人員乃至面試官自身對于這個預(yù)處理指令都是一知半解,所以今天在簡
書為大家詳細講解一下這個指令。

1.#pragma簡述:

在所有的預(yù)處理指令中,#Pragma 指令可能是最復(fù)雜的了,它的作用是設(shè)定編譯器的狀態(tài)或者是指示編譯器完成一些特定的動作。#pragma指令對每個編譯器給出了一個方法,在保持與C和C++語言完全兼容的情況下,給出主機或操作系統(tǒng)專有的特征。依據(jù)定義,編譯指示是機器或操作系統(tǒng)專有的,且對于每個編譯器都是不同的。 今天為大家說的就是其中的#pragma pack指令。

2.#pragma pack的作用:

這個其實點進這個帖子的人都懂,#pragma pack 的主要作用就是改變編譯器的內(nèi)存對齊方式,這個指令在網(wǎng)絡(luò)報文的處理中有著重要的作用,#pragma pack(n)是他最基本的用法,其作用是改變編譯器的對齊方式, 不使用這條指令的情況下,編譯器默認采取#pragma pack(8)也就是8字節(jié)的默認對齊方式,n值可以?。?code>1, 24, 816) 中任意一值。

3.#pragma pack詳細介紹:

想必大家也看煩了,那么下面我就開始為大家介紹#pragma pack的詳細用法:

3.1 #pragma pack(show):

#pragma pack(show)顯示當前內(nèi)存對齊的字節(jié)數(shù)。也就是packing aligment
我們常說編譯器默認8字節(jié)對齊我們怎么知道的呢?
如下圖所示:

image
image

在程序中#pragma pack(show)會在編譯階段提出一個警告,說明當前對齊字節(jié)數(shù)。

3.2 #pragma pack(push [, identifier] [, n])

單純使用#pragma pack(push)會將當前的對齊字節(jié)數(shù)壓入棧頂,并設(shè)置這個值為新的對齊字節(jié)數(shù), 就是說不會改變這個值。
  而使用#pragma pack(push, n) 會將當前的對齊字節(jié)數(shù)壓入棧頂,并設(shè)置n為新的對齊字節(jié)數(shù)。
  再就是這個#pragma pack(push, identifier [, n])會在上面的操作基礎(chǔ)上為這個對齊字節(jié)數(shù)附上一個標識符, 這里注意這個標識符只能以($、_字母)開始, 標識符中可以有($、_、字母數(shù)字),并且標識符不能是關(guān)鍵字(push, pop可以作為標識符)。這個標識符的作用我會在pop中詳細介紹。
push的使用:

image
image

3.3 #pragma pack(pop [, identifier] [, n])

同樣單純使用#pragma pack(pop)會彈出棧頂對齊字節(jié)數(shù),并設(shè)置其為新的內(nèi)存對齊字節(jié)數(shù)。

image
image

使用#pragma pack(pop, n)情況就不同了, 他會彈出棧頂并直接丟棄,設(shè)置n為其新的內(nèi)存對齊字節(jié)數(shù)。

image
image

#pragma pack(pop, identifier [, n])較為復(fù)雜,編譯器執(zhí)行這條執(zhí)行時會從棧頂向下順序查找匹配的identifier,找到identifier相同的這個數(shù)之后將從棧頂?shù)?code>identifier,包括找到identifier全部pop彈出, 若沒有找到則不進行任何操作。

image
image

由于前面提到的pushpop也可以作為關(guān)鍵字所以可以設(shè)計出很有戲劇效果的預(yù)處理頭:

image
image

#pragma pack一系列的預(yù)處理指令在網(wǎng)絡(luò)報文構(gòu)造中有著重要的應(yīng)用,是編譯器處理內(nèi)存的重要指令,同時我也希望各位面試官注意自身知識體系,不要再自己一知半解的情況下亂問問題,我會在下次寫一篇關(guān)于C++內(nèi)存對齊的詳細介紹敬請期待!

以上是原博客內(nèi)容

下面是我遇到的一點情況(見注釋):

#pragma pack(show)//默認內(nèi)存對其按照8個字節(jié),==8
#pragma pack(4)//將8個字節(jié)對齊改成了4個字節(jié)
#pragma pack(show)//==4
typedef struct
{
    uint32_t iDeviceType;                          // see above defines
    char     szPath[512];                          // device path to use in FZ_Open
    char     szShortName[32];                      // a more user friendly name
    char     szSerial[16];                         // device serial number
    uint32_t iReserved[64];
} FZ_DEVICE_INFO;
#pragma pack(show)//==4,沒有發(fā)生改變
#pragma pack()//將內(nèi)存對齊設(shè)置變成默認的8個字節(jié)
#pragma pack(show)//==8
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容