2012-11-08 27 views
8

可能重複:
Aliasing `T*` with `char*` is allowed. Is it also allowed the other way around?這是使用std :: array未定義的行爲嗎?

我使用charstd::array A S以保持未知原語類型,這是不超過10個字節長,像這樣的一個值:

std::array<char, 10> val; 
*reinterpret_cast<double*>(val.data()) = 6.3; 
//blah blah blah... 
double stuff = *reinterpret_cast<double*>(val.data()); 

我讀過那個來回穿越char *不是你嗎ndefined,因爲編譯器假定一個char *可以別名任何類型的值。當這個值放在對象內部(我認爲是)一個char s的數組時,這仍然有效嗎?

注意:我知道我可以在這裏使用聯合,但這會導致我正在做的大量樣板代碼,並且如果有必要,我想避免它,因此是問題。

+0

不同的問題,相同的答案。 – Dan

+0

同樣的問題,不同的單詞。 ; - ] – ildjarn

回答

13

是,std::array< char, 10 >不符合double的對齊要求,因此reinterpret_cast會引起UB。

改爲嘗試std::aligned_storage

+0

對齊!當然,這是我甚至沒有想到的。感謝那個鏈接,這正是我需要的。 – Dan

0

不要緊什麼陣列包含在。

標準甚至不考慮什麼東西包圍(它是基本的),但不支持轉換/從char序列。

要直接通過reinterpret_cast和賦值完成此操作,您需要使緩衝區正確對齊。

另一種方法是使用memcpy,它不關心對齊。

在一個相關的問題上,一般不是一個好主意,下降到二進制級別。例如,編譯器的簡單版本更改可能會使二進制序列化數據的文件無法訪問。無論如何,做這件事的主要驅動因素是性能考慮。

+0

它支持將任意的char *轉換爲double *嗎?我認爲指針轉換可能是有損的。考慮具有不同大小指針的ABI。 – Potatoswatter

+0

什麼樣的編譯器更改會導致這種情況發生? – Dan

+0

'char'指針與任何指針都具有細粒度的尋址分辨率,與'void'相同。如果緩衝區沒有正確對齊,指針轉換可能是有損的。無論如何,數據複製可以*效率低下*。 –

相關問題