亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

預處理指令#pragma pack詳解

2019-11-10 18:29:49
字體:
來源:轉載
供稿:網友

預處理指令#PRagma pack詳解

#pragma pack的大致作用即為改變編譯器的對齊方式,先從指令和定義上來分析其功能。 部分內容參考http://www.cnblogs.com/King-Gentleman/p/5297355.html 以及MSDN。

簡單理解#pragma

作為較為復雜的預處理指令之一,它的作用為更改編譯器的編譯狀態以及為特定的編譯器提供特定的編譯指示,這些指示是具體針對某一種(或某一些)編譯器的,其他編譯器可能不知道該指示的含義又或者對該指示有不同的理解,也即是說,#pragma的實現是與具體平臺相關的??梢院唵螌⑵淅斫鉃樵擃A處理指令是開發者和編譯器交互的一個工具。

#pragma pack指令說明

由于內存的讀取時間遠遠小于CPU的存儲速度,這里用設定數據結構的對齊系數,即犧牲空間來換取時間的思想來提高CPU的存儲效率。

這里先說編譯器的對齊配置。以vc6為例,vc6中的編譯選項有 /Zp[1|2|4|8|16] ,/Zp1表示以1字節邊界對齊,相應的,/Zpn表示以n字節邊界對齊。n字節邊界對齊的意思是說,一個成員的地址必須安排在成員的尺寸的整數倍地址上或者是n的整數倍地址上,取它們中的最小值。也就是: min ( sizeof ( member ), n) 實際上,1字節邊界對齊也就表示了結構成員之間沒有空洞。 /Zpn選項是應用于整個工程的,影響所有的參與編譯的結構。 要使用這個選項,可以在vc6中打開工程屬性頁,c/c++頁,選擇Code Generation分類,在Struct member alignment可以選擇。 而如果要專門針對某些結構定義使用對齊選項,可以使用#pragma pack編譯指令。指令語法如下: #pragma pack( [ show ] | [ push | pop ] [, identifier ] , n )

指令用法說明:

pack提供數據聲明級別的控制,對定義不起作用;調用pack時不指定參數,n將被設成默認值;一旦改變數據類型的alignment,直接效果就是占用memory的減少,但是performance會下降。

語法具體分析:

show:可選參數;顯示當前packing aligment的字節數,以warning message的形式被顯示;push:可選參數;將當前指定的packing alignment數值進行壓棧操作,這里的棧是the internal compiler stack,同時設置當前的packing alignment為n;如果n沒有指定,則將當前的packing alignment數值壓棧;pop:可選參數;從internal compiler stack中刪除最頂端的record;如果沒有指定n,則當前棧頂record即為新的packing alignment數值;如果指定了n,則n將成為新的packing aligment數值;如果指定了identifier,則internal compiler stack中的record都將被pop直到identifier被找到,然后pop出identitier,同時設置packing alignment數值為當前棧頂的record;如果指定的identifier并不存在于internal compiler stack,則pop操作被忽略;identifier:可選參數;當同push一起使用時,賦予當前被壓入棧中的record一個名稱;當同pop一起使用時,從internal compiler stack中pop出所有的record直到identifier被pop出,如果identifier沒有被找到,則忽略pop操作;n:可選參數;指定packing的數值,以字節為單位;缺省數值是8,合法的數值分別是1、2、4、8、16。

先以#pragma pack(n)的使用舉例,該條指令功能與意義和/Zpn選項相同。#pragma pack(4)表示后續結構單元的對齊系數為4(具體規則見下面說明),#pragma pack()表示更改當前對齊系數為默認值(未修改時,工程對齊系數默認為8)。

#pragma pack(4) struct test{ char m1; short int m2; int m3; };#pragma pack() test t; printf("%d/n", sizeof(t));

上述代碼段執行結果為8,在初識時可能會誤作是12,為8的原因在于“結構體中的數據成員,除了第一個是始終放在最開始的地方,其它數據成員的地址必須是它本身大小或對齊參數兩者中較小的一個的倍數?!?/p>

數據對齊規則

經過上面這個例子,我們再來看對齊的規則。

復雜類型中各個成員按照它們被聲明的順序在內存中順序存儲,第一個成員的地址和整個類型的地址相同;每個成員分別對齊,即每個成員按自己的方式對齊,并最小化長度;規則就是每個成員按其類型的對齊參數(通常是這個類型的大?。┖椭付▽R參數中較小的一個對齊;結構體、聯合體或者類的數據成員,第一個放在偏移為0的地方;以后每個數據成員的對齊,按照#pragma pack指定的數值和這個數據成員自身長度兩個中比較小的那個進行;也就是說,當#pragma pack指定的值等于或者超過所有數據成員長度的時候,這個指定值的大小將不產生任何效果;復雜類型(如結構體)整體的對齊是按照結構體中長度最大的數據成員和#pragma pack指定值之間較小的那個值進行;這樣當數據成員為復雜類型(如結構體)時,可以最小化長度;復雜類型(如結構體)整體長度的計算必須取所用過的所有對齊參數的整數倍,不夠補空字節;也就是取所用過的所有對齊參數中最大的那個值的整數倍,因為對齊參數都是2的n次方;這樣在處理數組時可以保證每一項都邊界對齊。

另外,在相同的對齊方式下,結構體內部數據定義的順序不同,結構體整體占據內存空間也不同。舉例如下:

struct A {int a; // a的自身對齊值為4,偏移地址為0x00~0x03,a的起始地址0x00滿足0x00%4=0;char b; // b的自身對齊值為1,由于緊跟a之后的地址,即0x04滿足0x04%1=0,所以b存放在0x04地址空間short c; // c的自身對齊值為2,由于緊跟b之后的地址0x05%2不是0,而0x06%2=0,因此c的存放起始地址為0x06,存放在0x06~0x07空間。 // 在b和c之間的0x05地址 則補空字節。};

結構體A中包含了4字節長度的int一個,1字節長度的char一個和2字節長度的short型數據一個。所以A用到的空間應該是7字節。但是因為編譯器要對數據成員在空間上進行對齊。而由于結構體自身對齊值取數據成員中自身對齊值的最大值,即4,并且0x00~0x07的8字節空間滿足8%4=0,所以sizeof(strcut A)值為8。 現在把該結構體調整成員變量的順序。

struct B {char b; // b的自身對齊值為1,其起始地址為0x00,由于滿足0x00%1=0,所以b存放在0x00地址空間int a; // a的自身對齊值為4,由于緊跟b之后的地址0x01%4不是0,而0x04%4=0,因此c的存放起始地址為0x04,存放在0x04~0x07空間。 // 在b和a之間的0x01~0x03地址則補3個空字節。short c; // c的自身對齊值為2,由于緊跟a之后的地址0x08%2=0,因此c的存放起始地址為0x08,存放在0x08~0x09空間。};

這時候同樣是總共7個字節的變量,但是由于結構體自身對齊值取數據成員中自身對齊值的最大值,即4,并且0x00~0x09的10字節空間不滿足10%4=0,而12%4=0,所以sizeof(struct B)的值卻是12,即在緊跟c之后的0x0A~0x0B地址還需補兩個空字節,使得整個結構體占用的字節空間為12個字節。

現在我們使用預處理指令來指定結構體的對齊系數:

#pragma pack (2) /*指定按2字節對齊,等價于#pragma pack(push,2)*/struct C {char b;int a;short c;};#pragma pack () /*取消指定對齊,恢復缺省對齊,等價于#pragma pack(pop)*/

由上述規則4可知,結構體的對齊是按照結構體中長度最大的數據成員和#pragma pack指定值之間較小的那個值進行的,所以這里該值為2,sizeof(struct C)值是8。

這些例子引出了幾個具體的概念如下:

數據類型自身的對齊值:就是上面交代的基本數據類型的自身對齊值。指定對齊值:#pragma pack (value)時的指定對齊值value。結構體或者類的自身對齊值:其數據成員中自身對齊值最大的那個值。數據成員、結構體和類的有效對齊值:自身對齊值和指定對齊值中小的那個值。

其他參數使用舉例

#pragma pack(push, 1) // 將對齊系數1壓入internal compiler stack,同時設置當前的packing alignment為1#pragma pack(push, 4) // 將4也壓入棧,同時設置當前的packing alignment為4#pragma pack(show) // 顯示當前packing alignment的字節數#pragma pack(pop) // 彈出internal compiler stack頂端的一條記錄,這里彈出了4#pragma pack(show) // 此時頂端的packing alignment值為1, struct test{ char m1; short m2; int m3; };#pragma pack() // 更改為缺省值8 #pragma pack(show)

在VS2013下的編譯結果如下圖所示。 編譯結果

另外值得一提的是,在ARM平臺的編譯器中,沒有提供如“#pragma pack”這樣帶參數的對齊指令,只有一個關鍵字 __packed。 __packed 限定符將所有有效類型的對齊邊界設置為 1,如果一個結構沒有這個限定符,默認向表數能力最強的那個數據類型對齊。

typedef __packed struct { double dValue1; char u8Value2; int u32Value3;} ASampleStructor;

上例中,size值為13,說明1字節對齊后,該結構總長為13字節。去掉__packed對齊后,為16字節。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲影院高清在线| 欧美丰满少妇xxxxx做受| 日韩精品在线免费| 国产精品久久国产精品99gif| 欧美成人免费va影院高清| 亚洲国产成人精品久久| 国产精品高潮视频| 亚洲欧美在线一区二区| 精品亚洲国产成av人片传媒| 亚洲国产成人久久综合| 亚洲精品456在线播放狼人| 亚洲天堂男人天堂女人天堂| 中文欧美日本在线资源| 福利视频第一区| 在线亚洲男人天堂| 日韩在线观看免费| 欧美亚洲另类视频| 国内揄拍国内精品| 久久国产精品久久久| 性欧美暴力猛交69hd| 亚洲免费人成在线视频观看| 亚洲成人激情在线观看| 日韩精品在线视频美女| 国产97人人超碰caoprom| 成人久久精品视频| 欧美在线欧美在线| 视频一区视频二区国产精品| 亚洲精品网址在线观看| 成人精品一区二区三区电影免费| 在线色欧美三级视频| 97在线视频免费播放| 欧美另类极品videosbestfree| 久久亚洲国产精品| 91精品国产色综合久久不卡98| 日韩乱码在线视频| 久久久久久国产| 亚洲人成免费电影| 国产丝袜精品视频| 亚洲欧美激情一区| 92裸体在线视频网站| 欧美日韩国产专区| 日韩av免费在线观看| 亚洲精品国产拍免费91在线| 日韩精品视频在线免费观看| 成人黄色在线观看| 久久夜精品va视频免费观看| 日韩电影大片中文字幕| 国产精品成人av在线| 国产精品香蕉av| 欧美福利小视频| 欧美性猛交xxxx免费看久久久| 久久综合久久八八| 91精品在线观看视频| 九九精品视频在线观看| 欧美福利在线观看| 国产精品视频自在线| 色综合色综合网色综合| 久久久噜噜噜久久| 精品视频偷偷看在线观看| 69影院欧美专区视频| 欧美激情第6页| 欧美孕妇孕交黑巨大网站| 国产不卡在线观看| 成人高h视频在线| 日本一本a高清免费不卡| 日韩在线精品一区| 欧美激情一级精品国产| 欧美黄网免费在线观看| 91牛牛免费视频| 一区二区三区美女xx视频| 欧美电影院免费观看| 国产中文日韩欧美| 日韩在线视频免费观看| 日韩av在线免费看| 日韩av黄色在线观看| 精品久久久国产| 亚洲成人动漫在线播放| 欧美日韩亚洲天堂| 九九久久综合网站| 欧美成人自拍视频| 日韩在线观看网站| 国产精品一区二区av影院萌芽| 亚洲无av在线中文字幕| 日本成人激情视频| 久久久久久有精品国产| 中文字幕国产日韩| 色综合天天狠天天透天天伊人| 日韩人在线观看| 欧美午夜激情小视频| 一级做a爰片久久毛片美女图片| 精品国产91乱高清在线观看| 2021久久精品国产99国产精品| 一本一本久久a久久精品牛牛影视| 久久69精品久久久久久久电影好| 91国在线精品国内播放| 热草久综合在线| 欧美激情亚洲自拍| 日韩毛片在线看| 日韩理论片久久| 岛国av在线不卡| 亚洲成人精品视频在线观看| 国产精品99导航| 日韩中文在线观看| 午夜精品久久久久久99热软件| 奇米四色中文综合久久| 久久精品国产亚洲一区二区| 在线观看成人黄色| 日韩免费高清在线观看| 日韩欧美亚洲成人| 精品国产一区二区三区久久| 亚洲欧美www| 国产精品中文字幕久久久| 大胆欧美人体视频| 国产精品美乳一区二区免费| 国产免费观看久久黄| 国产精品网红直播| 亚洲欧美日韩一区二区在线| 中文字幕亚洲字幕| 国产亚洲视频中文字幕视频| 欧美性色19p| 精品欧美国产一区二区三区| 国产精品视频网| 日韩av在线网| 精品人伦一区二区三区蜜桃网站| 日韩在线观看免费全集电视剧网站| 激情av一区二区| 这里只有精品久久| 中文字幕精品一区二区精品| 日韩精品中文字幕久久臀| 国产亚洲综合久久| 国产欧美日韩专区发布| 18一19gay欧美视频网站| 欧美午夜视频在线观看| 亚洲伊人久久大香线蕉av| 日韩经典第一页| 国产精品嫩草影院久久久| 国产日韩在线一区| 亚洲天堂男人天堂女人天堂| 色爱精品视频一区| 亚洲美女又黄又爽在线观看| 欧美激情图片区| 亚洲男人av在线| 欧美国产在线电影| 日韩欧亚中文在线| 在线丨暗呦小u女国产精品| 亚洲国产精品一区二区三区| 欧美成人网在线| 国产精品青青在线观看爽香蕉| 日韩中文在线不卡| 精品免费在线观看| 欧美日韩亚洲一区二区三区| 亚洲自拍另类欧美丝袜| 北条麻妃一区二区在线观看| 久久精品国产久精国产一老狼| 国产精品久久久久免费a∨| 一本色道久久综合亚洲精品小说| 国产一区二区三区三区在线观看| 亚洲xxx自由成熟| 这里精品视频免费| 亚洲欧美精品一区| 九九热这里只有精品6| 欧美激情精品久久久久久黑人| 亚洲美女在线视频| www.亚洲人.com|