当常量引用绑定到临时引用时,堆栈中会发生什么
What happens in the stack when a const reference is bound to a temporary?
C++标准允许将常量引用绑定到右值,从而延长临时的生存期,直到引用超出范围。但是,我无法弄清楚这实际上是如何编译的,让我用一个例子来解释:
std::string foo() {
return std::string("foo");
}
void bar() {
VeryBigObject obj;
// Perhaps do something with the big object
}
int main(int, char **) {
const std::string &foo_str = foo();
bar();
return 0;
}
据我所知,以 x86 架构为例,那里发生的事情是,首先调用函数 foo()
,并在堆栈中构造字符串对象,这意味着从rsp
寄存器中减去所需的空间量(假设 64 位架构); 之后,rsp
寄存器返回到其原始值, 释放函数foo()
正在填充的堆栈空间,并且,如果我理解正确,对bar()
的调用将使用该堆栈空间来构造VeryBigObject
,这将覆盖字符串。
考虑到所有这些,在调用程序集域中的foo()
后,如何延长字符串的生存期?
临时返回值将在main
的堆栈帧中构造,方法是从foo
的堆栈帧复制/移动临时值,或者更有可能使用 RVO 来省略副本并直接在调用方的帧中构造它。
绑定到引用后,临时将存在与引用一样长。实际上,临时变量的管理方式与具有相同范围的命名变量完全相同。
相关文章:
- 什么时候在C++中返回常量引用是个好主意
- 返回常量对象引用 (getter) 和仅返回字符串有什么区别?
- 在C++17中,引用const字符串的语义应该是什么
- 引用文件的适当方法是什么?
- 引用捕获和在 lambda 中通过引用发送参数有什么区别 (C++)
- C++有什么方法可以在既不调用函数模板也不提供其模板参数的情况下引用函数模板?
- 引用 std::any 或 not_yet_in_std::whatever 的惯用方式是什么?
- 在 Rust 中,指针和引用有什么区别?
- 为什么或在什么情况下,你会将参数作为C++中的引用(或指针)传递给函数?
- 获取通用/前向引用地址有什么意义?
- 返回引用实例和非引用实例(return mystr & vs mystr)之间的区别是什么?
- 删除对象(具有不同类型)的引用时会发生什么情况?
- 对于具有引用返回类型的搜索算法,默认返回值应该是什么?
- 普通的右值引用和 std::forward 返回的引用有什么区别?
- 通过引用函数传递指针参数是什么意思?
- C++ 中的引用范围是什么?
- 将引用绑定到指针的语法是什么?(各种)
- constexpr引用有什么用吗
- 对struct::struct的未定义引用是什么意思
- 什么是常量指针常量引用类型的参数?(const X* const & p)