以下代码愚弄nullptr
指针和引用:
#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
关键字)?
奖金问题:是否有已知的编译器/优化选项,这实际上会导致上面的代码做出意外/崩溃的事情?例如,是否有任何编译器的标志,它会在初始化引用的地方为nullptr
生成隐式断言,包括从*ptr
传递引用参数?
好奇的示例输出,没什么意外的:
ip=(nil) &ir=(nil)
printAddr (nil)
printAddr (nil)
答案 0 :(得分:6)
// 2. dereference a nullptr pointer and pass it as reference
取消引用空指针是未定义行为,因此无论您将其作为引用还是按值传递,事实是您已取消引用它并因此调用UB,这意味着从那一点开始所有的赌注都已关闭。
你已经在这里调用了UB:
int &ir = *ip; //ip is null, you cannot deref it without invoking UB.
答案 1 :(得分:1)
由于ir
只是*ip
的影子,因此不会导致自身未定义的行为。
未定义的行为是使用指向nullptr_t
的指针。我的意思是使用*ip
。因此
int &ir = *ip;
^^^
导致UB。