[英]Does accessing the 4 bytes of a float break C++ aliasing rules
我需要讀取文件的二進制內容並將提取的字節轉換為單精度浮點數。 此處已詢問如何執行此操作。 這個問題確實有正確的答案,但我想知道一個特定的答案是否真的有效 C++ 代碼。
該答案給出了以下代碼:
float bytesToFloat(uint8_t *bytes, bool big_endian) {
float f;
uint8_t *f_ptr = (uint8_t *) &f;
if (big_endian) {
f_ptr[3] = bytes[0];
f_ptr[2] = bytes[1];
f_ptr[1] = bytes[2];
f_ptr[0] = bytes[3];
} else {
f_ptr[3] = bytes[3];
f_ptr[2] = bytes[2];
f_ptr[1] = bytes[1];
f_ptr[0] = bytes[0];
}
return f;
}
這實際上是有效的 C++ 代碼嗎? 我不確定它是否違反任何別名規則。
請注意,我針對的是具有大端字節序的平台,其中保證浮點數至少為 32 位長。
這實際上是有效的 C++ 代碼嗎?
可能是的。 它有一些先決條件:
std::uint8_t
必須是unsigned char
的別名sizeof(float)
必須為 4bytes + 3
不能溢出緩沖區。如果前兩個不成立,您可以添加檢查以確保安全編譯失敗:
static_assert(std::is_same_v<unsigned char, std::uint8_t>);
static_assert(sizeof(float) == 4);
我不確定它是否違反任何別名規則。
unsigned char
不受此類限制。 std::uint8_t
如果已定義,實際上是unsigned char
的別名,在這種情況下,顯示的程序定義明確。 從技術上講,規則並不能保證這一點,但上述檢查將處理不適用的理論情況。
float 保證至少有32 位長。
代碼必須恰好是 32 位長才能工作。 它還必須具有與序列化浮點數的系統上完全相同的位級格式。 如果它的兩端都是標准的 IEE-754 單精度,那么你很好; 否則所有的賭注都沒有了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.