2012-12-10 39 views
14

可能重複:
Practical Use of Zero-Length Bitfields什麼是零寬度位字段

爲什麼零寬度位字段,以及爲什麼需要它的一些結構?

struct foo { 
    int a:3; 
    int b:2; 
    int  :0; // Force alignment to next boundary. 
    int c:4; 
    int d:3; 
}; 

int main() 
{ 
     int i = 0xFFFF; 
     struct foo *f = (struct foo *)&i; 
     printf("a=%d\nb=%d\nc=%d\nd=%d\n", f->a, f->b, f->c, f->d); 
     return 0; 
} 

上述程序的輸出是

[email protected]:~/programs/test$ ./a.out 
a=-1 
b=-1 
c=-8 
d=0 

請解釋爲什麼這些值是負的,並且該結構內這些變量的存儲器佈局?

+1

這是微軟的回答,我建議你看看:http://msdn.microsoft.com/en-us/library/ewwyfdbe(v=vs。 71).aspx,即使如此,對齊總是依賴於編譯器。 –

+0

結構{0} {0} {0}} int a:3; int b:2; int:0; int c:4; int d:3; }; 這將給佈局 000aaabb 0ccccddd 而不是:0; 0000aaab bccccddd 0寬度字段表示應在下一個原子實體(char)上設置以下位域。聲明爲位字段的數據的排序是從低位到高位,或者取決於您的體系結構的其他方式。 –

回答

8

this first hit on a Google search

爲0的長度的比特字段必須是未命名的。未命名的位字段不能被引用或初始化。零寬度位字段可以使下一個字段在下一個容器邊界上對齊,其中容器與位字段的基礎類型具有相同的大小。

至於你的問題的第二部分,您可以設置位域的一些在你的結構爲全1,由於這些字段簽署則會導致這些字段爲負值。如果將整個結構設置爲1並查看有符號和無符號表示中的值,則可以更有效地看到這一點。

int main() 
{ 
    struct foo f; 
    memset(&f, 0xff, sizeof(f)); 
    printf("a=%d\nb=%d\nc=%d\nd=%d\n", f.a, f.b, f.c, f.d); // print fields as signed 
    printf("a=%u\nb=%u\nc=%u\nd=%u\n", f.a, f.b, f.c, f.d); // print fields as unsigned 
    return 0; 
} 
3

內存佈局是「它取決於」,你不能指望任何特定的編譯器佈局。實際上,通過更改其設置,您可能會看到來自任何給定編譯器的不同佈局。不要試圖猜測,直覺或依靠佈局。

負面因素 - 您的所有元素均爲有符號的int,所以它們是負數,因爲您已將每位初始化爲1,所以您已設置了符號位。至於d - 擊敗我。錯字?

+0

你沒有回答這個問題的主要部分 - 零寬度位域的目的是什麼? –

1

數字是負數,因爲位域是帶符號的,即如果你有一個signed char變量,它的大小是8位,可以容納256個不同的值。其中一半爲正數,其餘爲負數,0爲最高位,表示符號(1表示負數,0表示正數)。關於零長度位字段,請參見:Practical Use of Zero-Length Bitfields

2

如上所述,here,零長度位域添加位域之間的對齊。如果我們在一行中有幾個位域,它們的佈局是緊湊的,但是如果我們想把它們中的一個與字節/字/雙字邊界對齊,我們需要在它和前一個之間放置一個零長度的位域。從上面的鏈接

例子:

struct on_off { 
        unsigned light : 1; 
        unsigned toaster : 1; 
        int count;   /* 4 bytes */ 
        unsigned ac : 4;  // this and 
        unsigned : 4;  // this and 
        unsigned clock : 1; // this bitfields are next to each other 
        unsigned : 0; 
        unsigned flag : 1; // this bitfield is at a 4 bytes boundary. 
       } kitchen ; 
相關問題