0

C++11. I'm trying to get a grasp on the basics of what constructor gets called when in what situation so the sake of preventing unnecessary copies and etc. In the below code sample I am not understanding why the Foo() constructor is getting called when I am passing in an argument. The only guess I can make is that the compiler might be optimizing away the constructor, but since this is changing behavior (by ignoring my cout statements) I would hope the compiler wouldn't do something like that.

class Foo {
  public:
    Foo() {
      cout << "vanilla constructor" << endl;
    }

    Foo(const Foo& f) {
      cout << "copy constructor" << endl;
    }

    Foo(Foo&& f) {
      cout << "move constructor" << endl;
    }
};

Foo getAFoo() {
  return Foo();
}

int main() {
  Foo f(getAFoo()); // prints "vanilla contructor" ???
  return 0;
}

What am I missing - why isn't the move constructor being called?

Justin
  • 75
  • 2
  • 6
  • If you're using gcc or clang compile with `-fno-elide-constructors` to see the copy/move constructors in action – Praetorian Mar 13 '15 at 04:59
  • What you are witnessing is called "Return Value Optimization." `getAFoo` is constructing the result directly into `Foo f`. – defube Mar 13 '15 at 05:01
  • Thanks - I guess I am just really struggling with the fact that the elision can throw away side effects. It seems contrary to the entire spirit of computer programming.. – Justin Mar 13 '15 at 05:17
  • This is actually one of the more useful "features" of the language. Some libraries require multiple nested calls that sometimes just forward objects. In these situations, the reduction of overhead has a significant impact on performance. – defube Mar 13 '15 at 05:21
  • 2
    Normally you're correct, removing the constructor calls changes the observable behavior, specifically in terms of `cout` usage, and in general the optimizer is not allowed to do things that change observable behavior. But there is a special rule that allows eliding copy/move in certain cases, no matter if the change is observable. – Ben Voigt Mar 13 '15 at 05:27

0 Answers0