开发者

Copy constructor not being called on function result

开发者 https://www.devze.com 2023-03-31 14:25 出处:网络
GCC inlines a statement -- no matter how hard I try to prevent it. I tried -fno-inline -O0 __attribute__ ((noinline))

GCC inlines a statement -- no matter how hard I try to prevent it. I tried

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

No success! Here the code:

#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();
}

The unfortunate output of this (g++ (Ubuntu/Linaro 4.5.2-8ubuntu4) 开发者_StackOverflow中文版4.5.2) is

func()
A::A()

What happened to the statement A a = func(); ??

The reason for this experiment is that I would like to know what happens when execution comes to this statement (because I need control how this is done):

A a = func();

I read that the copy constructor is called when one does

A a = b;

(In this case the copy-constructor is called. But not in the case A a = func();) The function is inlined instead. I NEED control over this statement since my "struct A" in real life contains dynamically allocated data that needs to be taken care of.

Am I missing something obvious here ?!


No, this has nothing to do with the function being inlined. Inlining the function would not change observable behaviour.

This is an optimization called copy elision that allows the compiler to avoid a copy by constructing the return value directly at the destination. You can disable it with the g++ flag -fno-elide-constructors.

In any case, the dynamically allocated data should not be a problem. Assuming a sane copy constructor, the only difference you will see will be possibly better performance.


If struct A contains dynamically allocated data, then it's your responsibility to manage that memory in the appropriate destructor/constructor. Many classes manage dynamically allocated data and work just fine with ellided copies. RVO and NRVO are important optimizations.


In case anyone (like me) is really looking for avoiding inline:

-fkeep-inline-functions -fno-inline

-fkeep-inline-functions
Even if all calls to a given function are integrated, and the function is declared static, nevertheless output a separate run-time callable version of the function. This switch does not affect extern inline functions.

-fno-inline
Don't pay attention to the inline keyword. Normally this option is used to keep the compiler from expanding any functions inline. Note that if you are not optimizing, no functions can be expanded inline.

0

精彩评论

暂无评论...
验证码 换一张
取 消