静态引用引用临时变量

Ale*_*oft 3 c++

#include <iostream>

int getID ( int k ) {
    static int& r = k;
    return r++;
}

int main()
{
    int a = getID ( 10 );
    int b = getID ( 10 );
    std::cout << "a = " << a << ", b = " << b  << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我不明白为什么这个代码编译.

  1. 静态引用如何引用局部变量k,它将在函数调用结束时消失.
  2. 在第二次调用时,我们使用新变量重新初始化静态引用.请解释一下这里发生了什么,为什么静态REFERENCE可以"重新定义"(我想我不理解方法中对静态变量的引用的含义).

Chr*_*eck 5

  1. 该语言不会阻止您绑定对有限生命周期的对象的引用.这将使得使用引用变得非常困难.

    (它确实阻止你绑定对temporaries的引用.但是函数的参数是l值,就像局部变量一样,所以它是允许的.)

    但是,如果您编写代码,其中引用绑定到一个超出它的对象,并且您继续使用该引用,则会得到未定义的行为,不需要诊断,并且很可能是段错误.它与悬挂式指针基本相同C.

  2. 在第二个电话,你就不能重新绑定静态参考变量,新的临时.静态变量仅在一次调用函数时初始化一次.所有后续调用都会有效跳过该行.

如果你想要一种能够为你捕捉到这样的错误的语言,并确保你不会被悬挂的引用所困扰,你可以看看Rust.生锈编译器有一个"借用检查器",它会检查你的引用,而不像许多众所周知的垃圾收集语言那样强加运行时开销.但Rust没有静态变量,因此没有直接翻译该代码;)

在C++中,我猜想上面的错误可能会被像Coverity这样的静态分析工具捕获,它会在扫描代码时对代码进行一些生命周期检查.但是C++编译器不会为你做这件事,你需要使用第三方工具.