2012-05-21 79 views
2

我想使用cpp的位域功能。
但是我得到所有的奇怪behivours,我想知道如果有一種方法來約束編譯器。
結構/類位字段包裝

我想使用該位字段:

class MyBitField 
{ 
    uint32 a : 8; 
    uint32 b : 32; 
    uint32 c : 32; 
} 

現在使用此代碼:

uint8 rawData[9] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFF, 0xFF}; 
MyBitField \*pMyBitField = (MyBitField\*)rawData; 

我預計(在小尾數32位CPU):
A的pMyBitField的字段爲0x12,
pMyBitField的b字段爲0x9A785634,
a的字段o f pMyBitField爲0xFFFFDEBC。

編譯器選擇做出一些無法解釋的對齊。
我知道,如果你在位字段中使用不同的類型,你可能會對齊,但事實並非如此。
我該怎麼做?

讓我們專注於Visual Studio 2005,但任何其他env支持也會受到祝福。

*我讀了一些包裝文章,但沒有改變對齊問題。

謝謝!

+1

谷歌#pragma pack,這是一個指令,讓編譯器在結構中使用特定的對齊方式.... –

+0

嗨,託尼,請詳細說明$ pragma用法 – talel

+0

來自Google的第一個匹配項,具體涉及到你的編譯器,包括例子: http://msdn.microsoft.com/en-us/library/2e70t5y1(v=vs.80).aspx –

回答

2

我希望你的代碼不要編譯。 rawData有一個數組類型;此 隱式轉換爲指針,但無法隱式或顯式轉換爲類 類型。其餘的,編譯器如何佈局位字段的定義是實現 ,但在你的情況下,我認爲它是無關緊要的;在一臺32位的 機器上,一個32位的位域通常會強制編譯器使用下一個字,所以只有第一個位域有效。根據 編譯器的不同,它會導致編譯器將值置於高位 順序8位或低位8位(並且保留字的其餘部分未定義) 。

如果你需要匹配一個外部格式,做這個 可靠的唯一方法是逐字節,插入任何值是必要的,爲該 字節。

+1

Visual Studio確實建議英特爾/ AMD,其中CPU能夠進行不對齊的尋址(有時性能會受到影響)。我希望編譯器能夠遵循一個非性能優化對齊的包請求。 「可靠地做到這一點的唯一方法......」可能是真實的,如果你把可靠性和可移植性保持一致並且保證在編譯器版本中一致等等,但是如果你準備使用實現定義的行爲,它可能會被可靠地定義和實現。 .. –

+1

如果包裝是唯一的問題,並且您不關心可移植性,您可能可以使用雜注。實際上,隨時打包是一個問題,所以它是字節順序的,可能還有其他的東西。 –