2014-02-25 24 views
1

我在MSVC++ 2008中定義的以下結構:爲什麼「無符號」映射到MSVC C++中的32位?

struct{ 
Uint16 XDD; 
unsigned XDD_UI:8; 
unsigned XDD_CR:8; 
}byte; 

當在上述結構上做的sizeof它表明無符號使用32位來存儲數據。

  • 這是爲什麼呢,它與內存對齊有關嗎?
  • 我怎麼能強制編譯器只使用8位定義沒有 觸摸結構定義?
+1

請問你如何驗證'XDD'佔用32位的代碼? –

+0

我使用'sizeof()' – drcelus

+0

你可以在這裏找到一些特定於位域打包的信息:http://randomascii.wordpress.com/2010/06/06/bit-field-packing-with- visual-c/ – manlio

回答

4

當你寫unsigned,這是短期的unsigned int,這是32位Windows上。這意味着它的排列順序爲4。由於你的結構是對齊的,因此在XDDXDD_UI之間有兩個字節填充,並且在結構的末尾填充了兩個字節。如果你想被包裝結構,那麼你需要它打包

 
0-1 XDD 
2-3 <padding> 
4-4 XDD_UI 
5-5 XDD_CR 
6-7 <padding> 

你的結構是奠定了這個樣子。使用#pragma pack即可實現。但是,即使你這樣做,編譯器也會生成一個大小爲6的結構。這是因爲位域被打包到一個unsigned int中,所以你的兩個位域總是會消耗4個字節。

如果您確定您的位域被聲明爲大小不超過2個字節的類型,那麼您的結構將是4個字節。這對於一個對齊的結構來說也是如此。舉例來說,這個結構有大小4

struct s { 
    unsigned short XDD; 
    unsigned short XDD_UI:8; 
    unsigned short XDD_CR:8; 
}; 

但是,它會在我看來,是更明智的聲明你的結構無位字段:

struct s { 
    Uint16 XDD; 
    unsigned char XDD_UI; 
    unsigned char XDD_CR; 
}; 

你可以聲明結構排列,並有你想要的佈局。

+0

是否有任何有用的程序可以保證在C標準規定的規則下的任何一致性實現下工作,如果位域可以以編譯器認爲合適的任何方式進行分配,將不會保證工作?我明白規則是什麼,但我很好奇爲什麼編譯器不允許如果硬件可以正常處理,則提供將四個六位字段打包成三字節結構的方法。 – supercat

1
And how could I force the compiler to use only 8 bits as defined without touching the struct definition 

使用#pragma

#pragma pack(1) 
struct{ 
Uint16 XDD; 
unsigned XDD_UI:8; 
unsigned XDD_CR:8; 
}byte; 
#pragma pack() 
+0

使用'#pragma pack(1)'結構的大小仍然比預期的大。 – drcelus

-2

取決於編譯器和機器未簽名的可能是64位了。由於以前的處理器是32位的,因此使用32位來處理int變得很常見。但是我們不應該依賴int或unsigned來確定它的範圍。

char或unsgined char肯定是使用8位的方法。但是內部編譯器可能已經做了調整,將其用作4字節進行處理。

+0

不,'char'至少爲8位,就像'unsigned'至少爲16位一樣。 – MSalters

+0

但是sizeof char在C中總是1 lang – AgA

+0

是的,但是'CHAR_BIT'並不總是8。 – MSalters

相關問題