2013-04-23 136 views
3

下面的代碼周圍傻瓜與nullptr指針和參考:nullptr是否在C++中引用未定義的行爲?

#include <cstdio> 

void printRefAddr(int &ref) { 
    printf("printAddr %p\n", &ref); 
} 

int main() {  
    int *ip = nullptr; 
    int &ir = *ip; 

    // 1. get address of nullptr reference 
    printf("ip=%p &ir=%p\n", ip, &ir); 

    // 2. dereference a nullptr pointer and pass it as reference 
    printRefAddr(*ip); 

    // 3. pass nullptr reference 
    printRefAddr(ir); 

    return 0; 
} 

問題:在C++中的標準,被註釋語句1..3有效代碼或未定義的行爲?

這與C++的不同版本是相同還是不同的(舊版本當然會使用0而不是nullptr關鍵字)?

獎金問題:有沒有已知的編譯器/優化選項,這實際上會導致上面的代碼做一些意想不到的事情/崩潰?例如,是否有任何編譯器的標誌,它會在引用初始化的任何地方生成隱式斷言,包括從*ptr傳遞引用參數?


一個例子輸出爲好奇,沒有什麼意外:

ip=(nil) &ir=(nil) 
printAddr (nil) 
printAddr (nil) 
+0

空指針引用一直是UB。你有沒有搜索過? – sehe 2013-04-23 08:07:33

+3

當你第一次解除引用ip時,你已經在(1)之前獲得了UB方式。 – Xeo 2013-04-23 08:07:42

回答

6

// 2. dereference a nullptr pointer and pass it as reference

取消對NULL指針未定義行爲,所以無論你把它作爲一個參考或價值,事實是,你已經取消了它,因此調用UB,意思所有投注都從這一點開始。

你已經調用UB這裏:

int &ir = *ip; //ip is null, you cannot deref it without invoking UB. 
1

由於ir只是一個*ip陰影也不會造成對自己的未定義的行爲。

未定義的行爲是使用指向nullptr_t的指針。我的意思是使用*ip。因此,

int &ir = *ip; 
      ^^^ 

導致UB。