2013-10-09 13 views
2

我具有以下結構:是否位域的類型影響結構alignement

struct bf_struct1 
{ 
    uint64_t bf1 : 1; 
    uint64_t bf2 : 6; 
    uint64_t bf3 : 2; 
    uint64_t bf4 : 55; 
} 

struct bf_struct2 
{ 
    uint8_t bf1 : 1; 
    uint8_t bf2 : 6; 
    uint8_t bf3 : 2; 
    uint64_t bf4 : 55; 
} 

是否結構構件對準取決於類型的位字段成員的?

+1

sizeof()告訴你這兩個結構是什麼?如果他們都是8,我會回答「不」。 –

回答

1

horse's mouth

6.7.2。1結構和聯合說明
...
5位字段應該有一個類型,它的 _Bool, signed int合格或不合格的版本,無符號整型,或其他一些實現定義的類型。它是 實現 - 定義是否允許原子類型。
...
11實現可以分配足夠大的任何可尋址存儲單元來容納一個位域。 如果剩下足夠的空間,緊接在 結構中的另一位字段之後的位字段應打包到相同單元的相鄰位中。如果剩餘空間不足, 是否將不合適的位字段放入下一個單元或與相鄰單元重疊是否爲實現定義的 。單元內位字段的分配順序(高階至 低階或低階至高階)是實現定義的。未指定可尋址存儲單元的對齊方式 。

簡答:它可以,取決於實施。

1

是的,它可以影響它。在第一個例子中,所有的字段都可以放入一個64位的uint64-t,所以這個結構可能總共需要8個字節。然而,第二,總共可能是16個字節。前三個字段至少需要兩個字節(兩個uint8_t)。然後,55位的最後位字段將採用單個的uint64_t,其可能在8字節的邊界上對齊。因此,雖然實際佈局取決於編譯器,但這兩個示例中的位的位置將會不同(因爲在第二個示例中假定填充在uint64_t之前)

佈局可能類似於以下內容沒有精確的比例):

bf_struct1

+---------------+---------+---------+-----------------------------------+ 
| uint8_t | uint8_t | Padding | uint64_t       | 
+---------------+---------+---------+-----------------------------------+ 
| bf1, bf2, bf3   | 48-bits | bf4        | 
+---------------+---------+---------+-----------------------------------+ 

bf_struct2

+-----------------------------------+ 
|  uint64_t      | 
+-----------------------------------+ 
| bf1, bf2, bf3, bf4    | 
+-----------------------------------+ 
1
#include <stdio.h> 

#define uint64_t unsigned long long 
#define uint8_t unsigned char 

struct bf_struct1 
{ 
    uint64_t bf1 : 1; 
    uint64_t bf2 : 6; 
    uint64_t bf3 : 2; 
    uint64_t bf4 : 55; 
}; 

struct bf_struct2 
{ 
    uint8_t bf1 : 1; 
    uint8_t bf2 : 6; 
    uint8_t bf3 : 2; 
    uint64_t bf4 : 55; 
}; 
int main(){ 
    printf("%lu ", sizeof(struct bf_struct1)); 
    printf("%lu ", sizeof(struct bf_struct2)); 
    return 0; 
} 

8個結果16.所以我會說答案是肯定的。儘管gcc和clang同意我的機器,但編譯器依賴於即使 。你可以讓一些聯盟和 弄清楚對齊是什麼。

+0

對於每個系統,這對於每個編譯器都是不同的。標準中位字段的定義非常差。 – Lundin

2
Does the structure member alignment depend on type of a bitfield members? 

是的。

檢查byte offsetbit offset

但是,根據有效的對齊模式,包含位字段的聚合對齊規則不同。
enter image description here

這些規則是described Here

1
  • 整個比特字段的比對是未指定的行爲以及是否允許比特字段分配未對齊的是實現定義的行爲。
  • 位字段的位順序是實現定義的。
  • 由於上述兩種說法,編譯器可以自由地按照實現定義的方式自由添加填充位和填充字節,位於位字段內的任意位置。
  • uint64_t實際上是否允許位域內是實現定義的。所以代碼甚至可能不工作。

實際上沒有辦法告訴這個代碼甚至會做什麼,更不用說它如何受到對齊的影響,而無需閱讀特定編譯器的文檔。

相關問題