2014-05-13 25 views
5

閱讀this Q & A,我想p不應該是一個即使nullptrx0。我理解了嗎?這是一個nullptr?

int main() 
{ 
    int x = 0; 

    std::cin >> x; // Enter `0` 

    void *p = (void *)x; // or: void *p = reinterpret_cast<void*>(x); 


    if (!p) 
     std::cout << "p is nullptr" << std::endl; 
} 

在標準輸入進入0後,消息p is nullptr將在我的GCC顯示。 根據link,它不應該評估到nullptr,但結果不是我的期望。

是代碼未定義的行爲?或未指定的結果?爲什麼它評估爲nullptr

+2

您正在將一個具有0值的int賦值給一個void *指針(對於所有的意圖和目的而言,這可能只是一個榮耀的,可能更寬的int) - 仍然值爲0你期望'p'有什麼價值? –

+2

'if'實際上測試p == 0,當然它是。是否0 == nullptr是一個更有趣的問題(VC++ 2012說它確實是值得的)。 – dlf

+0

什麼是'nullptr'你在說C++/CLI嗎? 'NULL'與0一樣爲零,一些C++編碼人甚至使用'NULL',因爲它太不確定(而不是測試0或0L)。 –

回答

11

從C++ 11 5.2.10/5施放[expr.reinterpret.cast](強調)重釋:

積分型或枚舉類型的值可以是明確地 轉換爲指針。一個指針轉換爲一個足夠大的整數 大小(如果有這樣的實現存在)並返回相同的指針類型 將有其原始值; 指針之間的映射 和整數在其他情況下是實現定義的

從5.2.10/4 A相關位:

類型爲std的值:: nullptr_t可以被轉換成一個整體型; 該轉換具有與將 (void *)0轉換爲整數類型相同的含義和有效性。 [注意:reinterpret_cast不能是 ,用於將任何類型的值轉換爲std :: nullptr_t類型。末端 音符]

1

讓我們試着來回答你的問題:

有可能reinterpret_cast<void*>(x) != nullptr如果int x = 0。但它不是強制性的。其實,reinterpret_cast<void*>(x) == nullptr在大多數平臺但取決於任何一個是未定義的行爲。

2

的ISO/IEC 14882:2011§4.10/ 1(和§4.11/ 1構件指針)只說,一個_constant整數表達式整數類型的積分常量表達式prvalue計算結果爲零是一個空指針常量。

對於整數,唯一的要求是在§5.2.10/ 5,這表示的是:

的指針轉換爲足夠大小的整數(如果任何這樣的存在於實現)並回到相同的指針類型將有其原始值;指針和整數之間的映射在其他方面是實現定義的。

所以它也是實現定義是否整數值0轉換爲空指針或不。在大多數實現中,它確實如此,因爲它更容易。

+0

在第一句中複製並粘貼錯誤? 「整數常量表達式的常量整數表達式」看起來不正確。 –