2011-06-16 71 views
1
#pragma pack(2) 
struct a{ 
    unsigned a:1; 
    unsigned b:1; 
    int c; 
    unsigned d:4; 
    unsigned :4; 
    unsigned e:1; 
    unsigned :0; 
    unsigned f:1;} ; 

int main() 
{ 
    printf("%d",sizeof(struct a)); 
} 

以下程序的輸出在不使用雜注包時爲16,而在使用雜注包時爲10。請說明這是怎麼回事?使用位域的結構尺寸的輸出

+0

爲了好奇:你是否編譯32位或64位平臺? – paercebal 2011-06-16 08:51:03

+0

在32位編譯器上 – user484457 2011-06-16 09:36:18

回答

5

首先,#pragma s爲編譯器專用的,所以沒有你指定你的編譯器和CPU(也許編譯器版本和命令行選項),我們只能猜測。

但是,一個可能的解釋是,對於 「包(2)」 版本:

#pragma pack(2) 
struct a{ 
    unsigned a:1; // at byte offset 0, could be least- or most-significant bit 
    unsigned b:1; // also in byte 0, besides a 
    int c;   // explicitly requested this int be mis-aligned at byte 2 
        // seems you've 32-bit ints, so 4-byte are 2,3,4,5 
    unsigned d:4; // at byte 6 
    unsigned :4;  // also fits in byte 6 
    unsigned e:1; // in byte 7 
    unsigned :0;  // requests following field be aligned for unsigned type 
        // your unsigned int must be 32-bits, so this means 
        // following field must start at 0, 4, 8, 12 etc. 
        // so: skips rest of byte 7 and moves to 8 
    unsigned f:1; // occupies one bit of byte 8 
}; 

因爲填料是 「2」,並且已經使用從[0]到[8的9個字節]中,sizeof(a)被向上舍入到10

沒有你的編譯指示的默認將是4個字節/ 32位。所以,第一個int是在32位的地址對齊以便更快地訪問,跳過2和3並佔據字節4,5,6,7,即沿着由那些2跳過字節到字節9推e,和:0迫使以下字段是在第12字節的總大小是則舍入到32位字長,所以從圖13(對於字節[0]〜[12]),最高達16

4

#pragma pack(2)的效果純粹是實現定義的,所以 你真的應該閱讀關於它的文檔(但我可以猜出 )。如果沒有編譯指示,根據標準, 存在一個非位域元素或一個大小爲0的位域導致編譯器前進到下一個「單元」,因此在你的結構中,ab在 之前單元,c在第二,d和在第三e,和f在 第四。鑑於大小爲16,我猜想4個字節單位(這是今天幾乎普遍的 )。與#pragma pack(2),我猜想 基本單位是兩個字節,而不是四個。而且,這並不改變 的int的大小,因此c仍然是四個字節,但高於其他單位 只有兩個。總共有十個字節,所以我的猜測 可能不會太遠。