是nullptr引用在c++中的未定义行为

Are nullptr references undefined behaviour in C++?

本文关键字:未定义 c++ nullptr 引用      更新时间:2023-10-16

下面的代码使用了nullptr指针和引用:

#include <cstdio>
void printRefAddr(int &ref) {
    printf("printAddr %pn", &ref);
}
int main() {    
    int *ip = nullptr;
    int &ir = *ip;
    // 1. get address of nullptr reference
    printf("ip=%p &ir=%pn", ip, &ir);
    // 2. dereference a nullptr pointer and pass it as reference
    printRefAddr(*ip);
    // 3. pass nullptr reference
    printRefAddr(ir);
    return 0;
}

问题:在c++标准中,有注释语句1..有效的代码或未定义的行为?

这与不同版本的c++是相同的还是不同的(旧版本当然会使用0字面值而不是nullptr关键字)?

额外的问题:是否有已知的编译器/优化选项,这实际上会导致上面的代码做一些意想不到的/崩溃?例如,是否有任何编译器的标志,它会在初始化引用的任何地方为nullptr生成隐式断言,包括从*ptr传递引用参数?

好奇的输出示例,没有意外:

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

// 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.

由于ir只是*ip的影子,因此它本身不会引起未定义行为。

未定义的行为是使用指向nullptr_t的指针。我的意思是使用*ip。因此

int &ir = *ip;
          ^^^

引起UB