是否会在堆上分配内存以支持临时对象与const引用的嵌套绑定?

Dan*_*aum 3 c++

请考虑以下代码,它const以"嵌套"方式将临时对象绑定到引用:

#include <iostream>

std::string foo()
{
    return "abc";
}

std::string goo()
{
    const std::string & a = foo();
    return a;
}

int main()
{
    // Is a temporary allocated on the heap to support this, even for a moment?
    const std::string & b = goo();
}
Run Code Online (Sandbox Code Playgroud)

我一直试图理解编译器在内存存储方面必须做些什么才能支持这种"嵌套"结构.

我怀疑对于调用foo(),内存分配很简单:std::string当函数foo()退出时,将在堆栈上分配a的存储.

但是,编译器必须做什么来支持所引用的对象的存储b?函数的堆栈goo必须展开并"替换为" b引用的堆栈上的对象,但是为了展开堆栈goo,编译器是否需要在堆上暂时创建对象的副本(在复制之前)它回到不同位置的堆栈)?

或者编译器是否可以完成此构造的要求而不在堆上分配任何存储,即使是暂时的?

或者是它甚至可以将编译器使用相同的存储位置,以由所引用的对象b作为对象由称为a,而不做任何堆栈或在堆上的任何附加配置?

Lig*_*ica 7

我认为有你没有考虑到,这是因为你没有约束力的中间一步ba,而是到的副本a.这不是因为任何奇特的记忆恶作剧!

goo按值返回,因此,该值在所有常用机制内的full-expression范围内可用main.它要么在main堆栈框架中,要么在其他地方,或者(在这个设计的情况下)可能完全优化.

这里唯一的魔力就是它被保留main范围b之内,直到超出范围,因为它b是一个ref-to- const(而不是接近立即销毁).

那么,堆会以任何方式进入它吗?好吧,如果你有一堆,没有.如果你的意思是免费商店,那么,仍然没有.

  • @DanNissenbaum:显然事实并非如此,否则你永远无法从任何函数返回任何值,而且它实际上只是你问我们的基本机制.你寻找的"某个地方"是函数调用为其结果提供的内存中的位置,这几乎完全取决于你所指的_which_实现,因为它太低级别无法定义C++语言. (3认同)
  • @DanNissenbaum看到`<`http://stackoverflow.com/questions/10900885/are-there-stackless-or-heapless-implementation-of-c`>` - 显然有大型机真正的编译器创建一个链表在"堆"上处理自动存储. (2认同)