2013-10-15 71 views
2

如果我們有位域的結構,那麼後續成員如何在結構中對齊?請看下面的代碼:具有位域的結構中的偏移量

struct A{ 
    int a:1; 
    char b;  // at offset 1 
}; 

struct B{ 
    int a:16; 
    int b: 17; 
    char c;  // at offset 7 
}; 

printf("Size of A: %d\n", (int)sizeof(struct A)); 
printf("Offset of b in A: %d\n", (int)offsetof(struct A, b)); 

printf("Size of B: %d\n", (int)sizeof(struct B)); 
printf("Offset of c in B: %d\n", (int)offsetof(struct B, c)); 

輸出:

Size of A: 4 
Offset of b in A: 1 
Size of B: 8 
Offset of c in B: 7 

這裏,在第一種情況下,b只是在結構中沒有任何填充第二字節分配。但是,在第二種情況下,當位字段溢出4個字節時,c被分配在最後的(第8個)字節中。

第二種情況發生了什麼?一般來說,涉及位域的結構中的填充規則是什麼?

+0

一般的規則是:編譯器可以墊和對齊的東西在它想要的任何方式。所有編譯器都提供了實現定義的擴展來控制字段的打包方式,如果您關心它們,您應該使用它們。 – DanielKO

+0

[位域的類型是否影響結構對齊]的可能的重複,並且還讀取[this]( http://stackoverflow.com/questions/6043483/why-bit-endianness-is-an-issue-in-bitfields/6044223#6044223)。 – Lundin

回答

2

後續成員在結構中是如何對齊的?

沒有人知道。這是實現定義的行爲,因此也是編譯器特有的。

第二種情況發生了什麼?

編譯器可能添加了填充字節或填充位。或者結構的位順序可能與您預期的不同。結構的第一項不一定包含MSB。

在涉及位域的結構中填充的規則是什麼?

編譯器可以自由添加任何的填充字節(和填充比特的位域),在結構的任何地方,只要它不是在結構的最開始做。

該標準定義的位域非常差。除了在內存中的隨機位置分配布爾標誌塊之外,其他任何東西都基本沒有用處。我會建議您使用純整數的按位運算符來代替。然後你得到100%確定性的便攜式代碼。

+1

_unsigned_整數上的按位運算符。 –

+0

@ElchononEdelson就這樣:) – Lundin

-2

我會舉一個小例子。希望這個可以明確: 考慮兩種結構:

struct { 
    char a; 
    int b; 
    char c; 
} X; 

對比。

struct { 
    char a; 
    char b; 
    int c; 
} Y; 

關於下面的評論多一點解釋:

所有下面不是100%,但結構將在32位的系統,可以構成常見的方式,其中int是32位:

結構X:

|  |  |  |  |  |  |  |  |  |  |  |  | 
char pad pad pad ---------int---------- char pad pad pad = 12 bytes 

結構Y:

|  |  |  |  |  |  |  |  | 
char char pad pad ---------int----------  = 8 bytes 

謝謝

一些參考::

Data structure Alignment-wikipedia