2013-04-23 133 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。