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

问题描述 投票:6回答:3

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()的情况下;)函数是内联的。我需要控制这个语句,因为我现实生活中的“struct A”包含需要处理的动态分配数据。

我在这里错过了一些明显的东西吗?

c++ inline variable-assignment
3个回答
18
投票

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

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

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


6
投票

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


3
投票

如果有人(像我)真的想要避免inline

-fkeep-inline-functions -fno-inline

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

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

© www.soinside.com 2019 - 2024. All rights reserved.