2016-08-03 119 views
0

float值的位模式複製到uint32_t或反之亦然(而不是它們),我們可以使用std::copymemcpy複製位字節到字節。另一種方法是如下使用reinterpret_cast複製位模式:浮點數到uint32_t

float f = 0.5f; 
uint32_t i = *reinterpret_cast<uint32_t*>(&f); 

uint32_t i; 
reinterpret_cast<float&>(i) = 10; 

但是有一個claim是說,兩名reinterpret_cast上面使用,調用未定義的行爲。

這是真的嗎?怎麼樣?

+1

正如答案所述,它是UB。一個斷言「sizeof(uint32_t)== sizeof(float)'雖然應該是所有你需要確信它會起作用的。 – NathanOliver

+0

@NathanOliver但是,如果編譯器進行基於類型的別名優化,那麼如果你不提供'-fno-strict-aliasing'或其他東西,它可以合理地破壞行爲。 – TartanLlama

+0

@TartanLlama好點。檢查'alignof'也可能是需要的。 – NathanOliver

回答

6

對,這是不確定的行爲,因爲它破壞了嚴格別名規則:

[basic.lval]/10:如果一個程序試圖通過的其他一個glvalue比 以下類型之一來訪問對象的存儲值的行爲是未定義 - 動態類型的對象,

- 動態類型的對象的CV-合格版本,

- 類似於一個類型(在4.4中定義的)到t他動態對象的類型,

- 一個類型是有符號或對應的動態對象的類型無符號類型,

- 在所述簽名或相應於CV-合格的無符號類型的類型對象的動態類型 的版本,

- 在其元素或非元素中包含上述類型之一的聚合或聯合類型靜態數據成員(包括遞歸的元素或非靜態數據成員的亞集團 或包含的聯盟),

- 一種類型,它是對象的動態類型的基本類型(可能是cv-qualifded),

- char或unsigned char類型。

由於uint32_t在嘗試訪問float類型的對象時沒有出現上述情況,因此行爲未定義。