众所周知,没有空引用。
所以我尝试编译这行代码
int main{
int &surprise_reference=*(int*)0;
return 0;}
令我惊讶的是,这段代码没有一个警告 然后我将代码更改为
int main() {
int&suprise_reference=*(int*)0;
if(&suprise_reference==0)
std::cout<<"you don't know references";
return 0;
}
程序的 输出 您不知道参考文献
这是否意味着取消引用空指针也会导致空引用?
请帮忙..
答案 0 :(得分:4)
你可以有一个最终指向NULL
的引用。这是未定义行为逃避编译器分析的结果。一个简单的例子就是用零填充整个堆的程序,包括存储引用的地址。显然,如果你这样做,那么引用将指向内存地址为零。
C ++标准禁止创建对 NULL
类型的引用,而不是引用NULL
。并且所有类型安全性仅在编译器能够推断出相关类型的情况下才会强制执行 - 使用硬C风格的强制转换会严重阻碍该类型。
答案 1 :(得分:3)
您的实验表明它恰好在您的特定计算机上运行。这并不意味着它“好”。
特别是,这一行:
int &surprise_reference=*(int*)0;
是无效的C ++代码,因为(正如您所说),不允许引用指向NULL指针。做一些C ++标准不允许的事情的结果是未定义的行为。在这种特殊情况下,在您的特定计算机上,未定义的行为恰好是非常良性的,但这并不能使其可预测,或者总是正常。
有关详细信息,请参阅https://isocpp.org/wiki/faq/references#refs-vs-ptrs。他们特别指出的一点是,因为编译器知道创建一个空引用是非法的,它可能会假设你没有这样做 - 例如,如果你有一个函数需要p
作为参数,你写
int &q = *(int*)p;
if (p == NULL)
...
它可以从引用创建中得出结论p
已知为非NULL,并优化掉检查。然后,如果传入p
的NULL指针,事情可能会出现严重错误。
(顺便说一句,那种假设和优化是未定义代码中的许多坏事发生的原因。)
答案 2 :(得分:1)
修复代码中的错误,谜团将消失。是的,带有bug的代码做的很奇怪。这不应该是令人惊讶的,也没有任何深刻的意义。