2013-01-25 15 views
2

同時通過使用reinterpret_cast將整數轉換爲浮點數更改內存的內容。值更改,同時reinterpret_cast

例如,

float fDest = 0; 
    __int32 nTempDest = -4808638; 

    fDest = *reinterpret_cast<float*>(&nTempDest); 

爲變量值nTempest十六進制表示爲'42 A0 B6 FF '但之後的reinterpret_cast fDest的含量爲'42 A0 F6 FF'。

任何人都可以給出答案,爲什麼第三個字節從b6變爲f6。

+1

我剛試過,它沒有改變。沒有理由爲什麼。 – user1610015

+4

需要證明(printf%x)和架構 – Mikhail

+3

@ user1610015:代碼違反了嚴格的別名規則,行爲未定義。當我嘗試時,我會得到'-nan'。 –

回答

0

您的代碼產生未定義行爲(UB)
reinterpret_cast只保證如果你從一個指針類型轉換到另一個指針類型並將其轉換回原來的指針類型,那麼你會得到原始數據。比其他任何生產UB [注1]

這是一個UB,因爲你不能依賴於一個事實,即:

sizeof(float) == sizeof(nTempDest) 

這不能保證true在所有的實現,絕對不是真的對於遵循嚴格別名的那些。並且如果實現不是你得到的是未定義的行爲。


[注1]有例外的規則,如果你需要依靠這些角落的規則,在游泳在洶涌的波濤,所以是絕對肯定的,你在做什麼。

+0

爲什麼這不正確? downvote的任何技術原因都會有所幫助。 –

+0

不是downvoter,但是如果你提到一個*指針*類型到另一個,它會更好。但是,我不記得這是無條件的。 – Potatoswatter

+1

我不能肯定地說,因爲我不是低調的選民,但我想這是因爲這不是唯一給定義行爲的東西。例如:「如果T1和T2是標準佈局類型,當」指向T1的類型「的prvalue v轉換爲類型」指向cv T2的指針「時,結果爲static_cast (static_cast (v)) (3.9),並且T2的對齊要求不比T1更嚴格,或者任何一種類型都是無效的。「 –

1

在純C++中,這實際上是未定義的行爲。然而,對於你所看到的有一個解釋。

我假設您給出的十六進制表示是來自內存的按字節視圖。顯然,你在一個小端的架構。所以我們從32位開始的數量是0xffb6a042,這實際上是-4808638的二進制補碼錶示。

作爲IEC 60559單精度浮點數(也是32位),0xffb6a042是一個負號,信號NaN。在的NaN該表示具有形式(二進制)

s1111111 1qxxxxxx xxxxxxxx xxxxxxxx 

這裏s爲符號中,x是一個靜態NaN和q = 0的任意的且q = 1的用於信令的NaN。

現在你正在使用信號南,因爲你將它分配給fDest。如果浮點信號處於活動狀態,則會引發浮點無效異常。默認情況下,這些例外被忽略,並且在傳播時信號NaN值被「靜默」。

所以:在分配給fDest時,NaN被傳播並且實現通過設置位22將它轉換爲安靜的NaN。這是您觀察到的變化。