#pragma pack 指令詳解!

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

1.#pragma簡述:

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

2.#pragma pack的作用:

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

3.#pragma pack詳細介紹:

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

3.1 #pragma pack(show):

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

QQ截圖20160525221002.png

QQ截圖20160525221034.png

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

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

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

QQ截圖20160525222634.png

QQ截圖20160525222751.png

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

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

QQ截圖20160525223331.png

QQ截圖20160525223345.png

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

QQ截圖20160525223816.png

QQ截圖20160525223827.png

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

QQ截圖20160525225453.png

QQ截圖20160525225517.png

    由于前面提到的pushpop也可以作為關鍵字所以可以設計出很有戲劇效果的預處理頭:

QQ截圖20160525225821.png

QQ截圖20160525225834.png

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

簡書●null122轉載請注明出處

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容