2016-12-23 24 views
3

簽名是reinterpret_cast安全的這一點,是它這樣做的最佳方式?寫有符號整數,就好像它是在C++

例如,在下面的代碼中,我有一個名爲ibytestream的類,它允許從中讀取uint16_t s和int16_t s。 ibytestream::nextvector<unsigned char>::iterator

inline ibytestream& operator>>(ibytestream& stream, uint16_t& data) { 
    data = 0; 
    data |= *stream.next++; 
    data <<= 8; 
    data |= *stream.next++; 
    return stream; 
} 

inline ibytestream& operator>>(ibytestream& stream, int16_t& data) { 
    return stream >> reinterpret_cast<uint16_t&>(data); 
} 

我不想重複的代碼轉換字節爲整數,所以我用reinterpret_cast的簽名版本重用無符號版本的代碼。它可以在我的機器上正常工作,但它是否可以在其他現代機器上運行?

+0

這是不是違反了嚴格別名規則? http://stackoverflow.com/q/98650/417197 –

+1

@Andre規則允許的整數類型及其無/有符號變種 –

回答

3

是的,這是安全的。標準的

三個部分適用於做出這個確定:

  1. 的對齊要求符號和無符號類型相同
  2. 指針指針之間投射到類型具有相同的對準要求被允許
  3. 當執行glvalues之間的轉換,如果相應指針之間的轉換有效,則轉換有效。

對於每個標準符號整數類型,存在一個相應的(但不同)的標準的無符號整數類型:unsigned charunsigned short intunsigned intunsigned long int, 和unsigned long long int,其中的每一個佔據相同量的存儲並具有相同的對齊要求。

對象指針可以顯式轉換爲不同類型的對象指針。轉換類型的prvalue「指針T1」的類型「指針T2」(其​​中,T1和T2是對象類型,並且其中T2的對準要求並不比T1的更嚴格的),並返回到其原始類型產生的原始指針值。

類型T1的glvalue表達可以轉換爲類型「參照T2」如果類型「指針T1」的表達可顯式轉換爲類型「指針T2」使用的reinterpret_cast。結果是指 同一個對象作爲源glvalue,但與指定的類型。

+0

我想你錯過了M.M在他的評論中提到的部分;您可以通過相應的無符號類型的表達式訪問有符號的整數對象。 – MSalters

1

是的,這應該是完全正常的。 (整數和字節數組之間移動具有潛在的字節序的問題,但是這是一個適用於有符號和無符號數另當別論。)

完全不同的東西:該位:

data = 0; 
data |= *stream.next++; 

...能被簡化:

data = *stream.next++; 
+0

我不認爲我的代碼將排列順序問題之間的混淆。字節將始終以big-endian讀取,而不管底層機器的字節順序如何。另外,我沒有做簡化,所以代碼看起來是一致的(即'data | = * stream。下一個++;'重複多行),我會假設我的編譯器足夠聰明,可以優化它。 – Bernard

+0

這只是一個問題,如果你需要跨體系結構的可移植性,而且看起來你不需要它。都好。 –

相關問題