右值引用如何绑定到引擎盖后面的临时值(右值)

How Rvalue references bind to a temporary value (rvalue) behind the hood

我感兴趣的是下面的代码:

int&& c = 2;
c++;
std::cout << c; //3

将变量 'c' 保存在内存中?

编译器是如何实现机器级别的引用的?它是否为它预留了任何内存?如果有,在哪里?还是保存在 CPU 寄存器中?

引用是否绑定到 lifetime-extended 临时是一个 属性,它在 compile-time 处为特定引用确定。

例如

{
    int x = 2;
    int&& c = std::move(x);
    c++;
    std::cout << c; //3
}

std::move(x) 的值类别是 xvalue,因此不会导致创建其生命周期会延长的临时文件。

另一方面

{
    int&& c = 2;
    c++;
    std::cout << c; //3
}

初始化表达式 2 是纯右值。纯右值需要具体化为引用可以绑定的临时值。因为具体化直接发生在绑定引用之前,所以临时对象的生命周期被延长以匹配引用的生命周期。

实际上,这两个片段做同样的事情,编译器可以简单地将第二个片段转换为第一个片段。因此,通常的对象存储规则适用。 int 对象(变量或临时对象)通常存储在堆栈或寄存器中,具体取决于编译器最终是否需要它具有地址。引用通常类似于指针实现,也在堆栈或寄存器中实现。

然而,在这样一个简单的例子中,编译器根本不需要存储引用,因为它知道引用所引用的变量或临时变量存储在函数中的什么位置。在机器指令中,引用的所有使用都可以简单地替换为对象的内存或寄存器引用。

实际上,该片段将等同于

{
    int c = 2;
    c++;
    std::cout << c; //3
}

此外,通常的优化适用,编译器将在您的问题中简单地执行 constant-propagation 并看到您一直输出相同的数字。它不是存储变量或引用,而是可以将整个事物优化为 std::cout << 3;.