复制构造函数未在函数结果上调用

时间:2011-08-30 13:55:03

标签: c++ inline variable-assignment

GCC概述了一份声明 - 无论我多么努力地阻止它。我试过了

  • -fno-inline
  • -O0
  • __attribute__ ((noinline))
  • dummy asm("")

没有成功! 代码如下:

#include<iostream>

using namespace std;

struct A {
  A() {cout << "A::A()" <<endl; }
  A(const A& a) {cout << "A::A(copy)" <<endl; }
  A& operator=(const A& a) {cout << "A::=()" <<endl; return *this;}
};

A __attribute__ ((noinline)) func() 
{
  cout << "func()" << endl;
  A loc;
  asm("");
  return loc;
}

int main() {
  A a = func();
}

这个(g ++(Ubuntu / Linaro 4.5.2-8ubuntu4)4.5.2)的不幸输出是

func()
A::A()

声明A a = func(); ??

这个实验的原因是我想知道执行到这个语句时会发生什么(因为我需要控制如何完成):

A a = func();

我读到了复制构造函数被调用时

A a = b;

(在这种情况下,复制构造函数被调用。但不是在A a = func();)的情况下 该函数是内联的。因为我的“结构A”,我需要控制这个语句 在现实生活中包含需要处理的动态分配数据。

我错过了一些明显的东西吗?!

3 个答案:

答案 0 :(得分:18)

不,这与内联函数无关。内联函数不会改变可观察的行为。

这是一个名为copy elision的优化,它允许编译器通过直接在目标处构造返回值来避免复制。您可以使用g ++标志-fno-elide-constructors禁用它。

在任何情况下,动态分配的数据应该不是问题。假设一个理智的复制构造函数,您将看到的唯一区别可能是更好的性能。

答案 1 :(得分:6)

如果struct A包含动态分配的数据,那么您有责任在适当的析构函数/构造函数中管理该内存。许多类管理动态分配的数据,并且使用椭圆形副本工作得很好。 RVO和NRVO是重要的优化。

答案 2 :(得分:3)

如果有人(像我一样)真的在寻找避免inline

-fkeep-inline-functions -fno-inline
  

-fkeep内联函数
  即使集成了对给定函数的所有调用,并且该函数被声明为静态,但仍然输出该函数的单独的运行时可调用版本。此开关不会影响外部内联函数。

     

-fno列直插
  不要注意内联关键字。通常,此选项用于防止编译器扩展任何内联函数。请注意,如果您没有进行优化,则不能内联扩展任何功能。