2016-09-23 75 views
2

我有這兩種結構: - 1.位字段中聯合在結構

typedef struct bitfield 
{ 
    unsigned int a:16; 
    unsigned int b:17; 
    union 
    {  
     unsigned int c:4; 
     unsigned int d:32; 
    }; 
}bfield; 

這種結構具有匿名聯合,當我計算該結構的尺寸 - 它出來是12個字節( 4 + 4 + 4)。這可以。

2.

typedef struct bitfield 
{ 
    unsigned int a:16; 
    unsigned int b:17; 
    union u 
    {  
     unsigned int c:4; 
     unsigned int d:32; 
    }; 
}bfield; 

但在32位機器打印該結構的大小的8個字節我DEVC++編譯器。我不明白爲什麼它會是8.

+0

幾乎沒有關於位域佈局的保證。說:32位'無符號'你的'結構'只能有8個字節,如果你的字節超過8位寬。請提供[mcve]。假設8位/字節,「struct」大小可以很好地爲16個字節。但這一切都取決於平臺。 – Olaf

+0

@Olaf無符號的默認寬度不相關,因爲他/她已經手動指定了每個字段的位寬。但我仍然同意,不可能將其打包爲只有8個字節。看到編譯器生成什麼代碼將是有趣的。 – jforberg

+0

但是我得到了與OP相同的結果:goo.gl/ASQO6Q – jforberg

回答

2

OP中的聯合聲明是不正確的(它不會執行OP想要的)。

它看起來只是一個聯合聲明,並沒有添加一個字段到結構中。

要麼將​​聯合字段聲明爲匿名,要麼聲明爲named。

請參見本例中(這裏還張貼:http://rextester.com/EPUEH77041

在這兩種情況下,結構的大小爲12個字節。

#include <iostream> 

typedef struct bitfield 
{ 
    unsigned int a:16; 
    unsigned int b:17; 
    union u 
    {  
    unsigned int c:4; 
    unsigned int d:32; 
    }U; 
}bfield; 


typedef struct bitfield2 
{ 
    unsigned int a:16; 
    unsigned int b:17; 
    union 
    {  
    unsigned int c:4; 
    unsigned int d:32; 
    }; 
}bfield2; 

int main() 
{ 
    std::cout << "Test bitfields1\n" << sizeof(bfield) << "\n"; 
    std::cout << "Test bitfields2\n" << sizeof(bfield2) << "\n"; 

    static volatile bfield y; 
    y.a=0x1234; 
    y.b = 0x1FF55; 
    y.U.d = 0x5a5a5a5a; 
    std::cout << std::hex << y.U.d << "\n"; 

    static volatile bfield2 x; 
    x.a=0x1234; 
    x.b = 0x1FF55; 
    x.d = 0x5a5a5a5a; 
    std::cout << std::hex << x.d << "\n"; 
} 
5

你的第一個例子聲明一個匿名的結構union

第二個示例聲明瞭一個結構,其中包含union的聲明,該聲明是noop。例如。

typedef struct bitfield 
{ 
    unsigned int a:16; 
    unsigned int b:17; 
    union u 
    {  
     unsigned int c:4; 
     unsigned int d:32; 
    }; 
}bfield; 

int main(void) { 
    struct bitfield b; 
    b.c=2; 
} 

將失敗,並

x.c:14:4: error: 'struct bitfield' has no member named 'c' 

編譯器會發出警告它

x.c:9:6: warning: declaration does not declare anything 

所以,你的問題有位域,但與匿名聯合沒什麼待辦事項。

+2

...然後繼續,你可能打算把u放在塊之後,而不是之前,所以你會得到'union {uint c; uint d} u' –

+0

嗯,實際上它是匿名的'union'與'union'的聲明,不僅是關於匿名'union'(或'structs')。 – Olaf

+0

@HaldeanBrown:這會讓'u'不再是一個匿名的'union'。不知道這是OP想要的。 – Olaf