【问题标题】:C++ understanding RVO (as compared to returning local variable reference)C++ 理解 RVO(与返回局部变量引用相比)
【发布时间】:2017-05-29 17:29:19
【问题描述】:

这是我使用 C++ 和学习的第一年。我目前正在阅读返回值优化(我使用 C++11 顺便说一句)。例如。这里https://en.wikipedia.org/wiki/Return_value_optimization,马上就会想到这些带有原始类型的初学者示例:

int& func1()
{
    int i = 1;
    return i;
} 
//error, 'i' was declared with automatic storage (in practice on the stack(?)) 
//and is undefined by the time function returns 

...还有这个:

int func1()
{
    int i = 1;
    return i;
}
//perfectly fine, 'i' is copied... (to previous stack frame... right?)

现在,我开始讨论这个问题,并尝试根据其他两个来理解它:

Simpleclass func1()
{
    return Simpleclass();
}

这里实际发生了什么?我知道大多数编译器都会对此进行优化,我要问的不是“如果”而是:

  • 优化的工作原理(接受的响应)
  • 它是否会干扰存储持续时间:堆栈/堆(旧:我是从堆栈复制还是在堆上创建并移动(通过引用)基本上是随机的吗?它取决于创建的对象大小吗? )
  • 使用明确的std::move不是更好吗?

【问题讨论】:

  • 我是从堆栈复制还是在堆上创建基本上是随机的不,它是在堆栈上创建的。
  • 为什么会涉及到堆?您链接的文章中很好地解释了实现。
  • 我明白了 n 的要点。河。 v. 现在优化。至于我为什么写“堆”,我的印象是更大的对象不适合堆栈,这也是它被称为“自动存储”声明的原因。但也许这是我误解的另一件事。

标签: c++ c++11


【解决方案1】:

在返回整数时,您不会看到 RVO 的任何效果。

但是,当返回这样的大对象时:

struct Huge { ... };

Huge makeHuge() {
    Huge h { x, y, x };
    h.doSomething();
    return h;
}

以下代码...

auto h = makeHuge();

...在 RVO 实现之后会像这样(伪代码)...

h_storage = allocate_from_stack(sizeof(Huge));
makeHuge(addressof(h_storage));
auto& h = *properly_aligned(h_storage);

... makeHuge 会编译成这样的东西...

void makeHuge(Huge* h_storage) // in fact this address can be
                               // inferred from the stack pointer
                               // (or just 'known' when inlining).
{
    phuge = operator (h_storage) new Huge(x, y, z);
    phuge->doSomething(); 
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-09
    • 1970-01-01
    • 2016-01-19
    • 1970-01-01
    • 1970-01-01
    • 2014-05-14
    • 1970-01-01
    相关资源
    最近更新 更多