2011-05-31 49 views
5

這是否正確?鑄造簽名到無符號

typedef unsigned int Index; 

enum 
{ 
    InvalidIndex = (Index) -1 
}; 

我已閱讀,它是跨平臺的不安全,但我在這麼多的「專業」的代碼看到了這一點......

+1

我希望你不要在每個問題的開始處寫「Hi」... – 2011-05-31 18:07:45

回答

6

你讀到的內容可能是出於恐懼,不確定和懷疑。無論你讀什麼的作者可能認爲(unsigned)-1正在下溢,並可能導致混亂的系統,位代表不會發生給你UINT_MAX你的麻煩。

但是,作者是錯誤的,因爲標準保證無符號值到達其範圍邊緣時環繞。不管涉及什麼位表示,(unsigned)-1std::numeric_limits<unsigned>::max()。期。

雖然我不確定它的好處在哪裏。你會得到那麼大的,最大的價值。如果那沒問題,我想你應該去。

+1

您可能不知道'enum'的基礎類型,但您知道它將能夠保存任何枚舉常量的值,否則您將收到編譯時錯誤。 'UINT_MAX'是一個值,這是枚舉常量可以採用的唯一合法值。 – 2011-05-31 18:21:51

+0

@JamesKanze:詹姆斯,這是一個相當不錯的觀點。 :) – 2011-05-31 18:22:41

0

不太清楚,如果這是實現定義,但鑄造-1(這顯然是有符號的)到一個無符號整數引起下溢,這通常會導致非常大的值(即INT_MAX)。

+2

編碼類似這樣的意圖通常是 – 2011-05-31 18:00:13

+0

它不是真正的下溢,因爲無符號值被定義爲環繞。 – 2011-05-31 18:02:01

4

如果你想得到UINT_MAX,我很確定這是實現它的最好方法。投1到unsigned保證產生UINT_MAX。它在評論中解釋。

+2

'UINT_MAX'。並且由於按位有符號的表示,它可以保證*但不*。這是保證,因爲轉換爲無符號類型執行模算術。它恰好發生了,2的補碼錶示使得位模式不變,但是在1s的補碼和符號量值中它確實改變了位模式,並且演員陣容保證了這一點。 – 2011-05-31 18:01:35

+0

你的意思是'INT_MAX',它的'UINT_MAX'在這裏與此無關。並不是因爲位,而是因爲標準說無符號值包裝。然後,當您再次轉換爲'signed'以在枚舉中使用(_if_基礎類型已簽名)時,您返回-1。 – 2011-05-31 18:03:23

+0

更正,謝謝你們兩位。 – slezica 2011-05-31 18:05:51

2

這是不安全的,因爲枚舉是什麼沒有明確定義。

有關更多信息,請參閱Are C++ enums signed or unsigned?

在一天結束的時候,你寫的東西看起來會在翻譯中變成(int)(unsigned int)(int),所以我不確定你想要完成什麼。

+0

這是完全安全的,因爲表達式的值是完美定義的,並且這個值可以在枚舉中表示,或者它是一個錯誤。 – 2011-05-31 18:23:51