从功能实现中返回结构

时间:2014-07-15 05:10:53

标签: c compiler-construction struct

在C和C ++中,我们可以从函数和方法返回结构或类:

class A final { public:
    int i;
    A(int n) { this->i=n; }
};
A function(void) {
    return A(4);
}
int main(void) {
    A result = function();
    return 0;
}

我想知道的是这是如何实现的?传统的观点是它被复制,从而产生成本:为了缓解,您可以将指针传递给结构而不返回任何内容。

但是,我不确定这是否(总是)必要的。例如,在上文中,从未在本地使用构造的结构。既然我们正在返回它,那么在弹出堆栈之前,数据是否无法直接填充到result变量的一个更高级别?

正如我所看到的,这样做的主要问题是被调用者函数需要知道调用者想要结果的位置。另一个问题是在更多递归函数的情况下:如果你要复制的最终变量是堆栈中的几层,那么被调用者找到正确位置会变得更加困难。根据我有限的编译器知识,我的猜测是,在返回后立即从调用者复制来自被调用者的struct

总的来说,我觉得这样的优化可能会很棘手。对于内联函数,我希望它是隐式发生的,如果结构从未在本地使用过,我看不出为什么它不能以这种方式实现的原因。但是,对于其他所有内容,我希望您尝试实现它时遇到的问题太大了,实际上通常只会复制它。

所以:

  • 内联:(隐式发生?)
  • 返回从未使用过的新结构:(发生?)
  • 递归:(任何并发症?)
  • 一般情况下:(不会发生?)

1 个答案:

答案 0 :(得分:0)

在C ++中,编译器经常使用copy elision习语(通常称为“返回值优化”)来避免在返回值时不必要的副本。至少,他们通常允许来做。

C ++标准,第12.8节:

  

当满足某些条件时,允许省略实现   复制/移动类对象的构造,即使构造函数   选择用于复制/移动操作和/或析构函数   对象有副作用。在这种情况下,实施处理   省略的复制/移动操作的源和目标只是两个   引用同一个对象的不同方式,以及对它的破坏   该对象发生在两个对象的后期   如果没有优化就会被破坏。

     

复制/移动操作的省略,称为复制省略,是   在下列情况下允许(可以合并到   消除多份副本)

     
      
  • 在函数的返回语句中,具有类返回类型,当时   expression是非易失性自动对象的名称(除了   一个函数或catch子句参数)具有相同的cv-不合格   键入函数返回类型,复制/移动操作即可   通过直接构造自动对象省略   函数的返回值

  •   
  • ...

  •