C++ 参考r值(r值的地址)

C++ 参考r值(r值的地址),c++,rvalue-reference,return-by-value,C++,Rvalue Reference,Return By Value,假设我们有一个按值返回的函数: int func() { int x = 10; // create local variable x with value of 5 return x; // create temporary copy of x which is returned, local variable x is destroyed } int main() { int y = func(); // temporary copy of x is copied to

假设我们有一个按值返回的函数:

int func() {
   int x = 10; // create local variable x with value of 5
   return x;  // create temporary copy of x which is returned, local variable x is destroyed
}

int main()
{
  int y = func(); // temporary copy of x is copied to y, when it hits`;` the temporary object is destroyed
  return 0;
}
如果我在上面的评论中说的话有错,请纠正我

现在,我们可以通过不断引用临时对象来延长其寿命

int main()
{
  const int & y = func();  // now the temporary object (R-value) is not destroyed when it hits `;` thus the life time is lenghtened.
  return 0;
}

问题是:由于我创建了一个应该销毁的临时对象的常量引用,这是否意味着
cout如注释中所述,将常量引用(或右值引用)指向临时对象会将其生存期延长到该引用之一


另外,这些临时对象(R值)存储在内存(i)中的什么位置 使用了基元类型int,但可以是class)

本标准未对此进行规定。但是,您可以查看最常见的编译器,了解它们的功能。从GCC开始,没有任何优化,您将得到

func():
  push rbp
  mov rbp, rsp
  mov DWORD PTR [rbp-4], 10
  mov eax, DWORD PTR [rbp-4]
  pop rbp
  ret
main:
  push rbp
  mov rbp, rsp
  sub rsp, 16
  call func()
  mov DWORD PTR [rbp-12], eax
  lea rax, [rbp-12]
  mov QWORD PTR [rbp-8], rax
  mov eax, 0
  leave
  ret

因此,返回值被推送到函数内部的EAX寄存器中,一旦返回,该值就会被推送到main()的堆栈框架中,就像您在main函数中创建了变量一样。您将在其他编译器中找到类似的结果。当启用优化时,显然会发生:编译器看到函数只返回一些常量值,并将其完全删除:

func():
  mov eax, 10
  ret
.LC0:
  .string "%i"
main:
  sub rsp, 24
  mov edi, OFFSET FLAT:.LC0
  xor eax, eax
  lea rsi, [rsp+12]
  mov DWORD PTR [rsp+12], 10
  call printf
  xor eax, eax
  add rsp, 24
  ret
在这里,我添加了一些printf()调用,它将输出临时s.t.的地址。这个程序并不是很简单。
因此,它创建了函数,但不需要调用它,只需将10写入本地堆栈帧中的某个空间。如果您只是按值使用它,它将被放入一个寄存器中,因为不需要地址。

您无法知道临时变量存储的位置。这是实现定义的。“那些存储在内存中的临时对象(R值)在哪里?”你为什么关心这些临时对象(R值)在内存中存储在哪里?这取决于你编译的平台的ABI。一个有趣的话题,但是没有C++本身关心的。“那么,这个地址代表什么?”嗯,地址是<代码> y>代码>?@ vvWoit,它是对象地址,但它是否在自由存储中,或者自动变量的地址,或者什么都不是C++指定的,它在实现过程中是不一样的。你为什么在乎?