8

The following code snippet causes the copy constructor to be called where I expected the move constructor to be called:

#include <cstdio>

struct Foo
{
    Foo() { puts("Foo gets built!"); }
    Foo(const Foo& foo) { puts("Foo gets copied!"); }
    Foo(Foo&& foo) { puts("Foo gets moved!"); }
};

struct Bar { Foo foo; };
Bar Meow() { Bar bar; return bar; }
int main() { Bar bar(Meow()); }

On VS11 Beta, in debug mode, this prints:

Foo gets built!
Foo gets copied!
Foo gets copied!

I checked the standard and Bar seems to meet all requirements to have a default move constructor automatically generated, yet that doesn't seem to happen unless there's another reason why the object cannot be moved. I've seen a lot of move and copy constructor related questions around here but I don't think anyone has had this specific issue.

Any pointers on what's going on here? Is this standard behaviour?

Trillian
  • 6,207
  • 1
  • 26
  • 36
  • Does `return std::move(bar);` change anything? BTW, gcc 4.7.0 calls the move constructor (with copy elision turned off). – Jesse Good Apr 18 '12 at 01:52
  • BTW, gcc 4.6.1 doesn't call either the copy or move ctor. – Michael Burr Apr 18 '12 at 01:53
  • g++ 4.5.3 only creates the object: "Foo gets built!" (copy elision), while with copy elision disabled it copies the object twice. Isn't a move constructor only called when you have an rvalue? I'm not entirely sure Meow() qualifies. – Misguided Apr 18 '12 at 02:00
  • 1
    If I explicitely declare a move constructor in Bar, it gets called, so this really is an issue with the generation of a default move constructor. – Trillian Apr 18 '12 at 02:04

1 Answers1

8

Unfortunately, VS11 doesn't provide a default move constructor. See Move Semantics in the Remarks section - to quote:

Unlike the default copy constructor, the compiler does not provide a default move constructor.

Fraser
  • 74,704
  • 20
  • 238
  • 215
  • Nice catch, thanks! Is that somehow allowed by the standard? If not I guess I'll open a bug on Microsoft Connect, even though they must be well aware of it. – Trillian Apr 18 '12 at 02:08
  • MS just haven't finished implementing all of the new C++11 features yet. There's more info at http://msdn.microsoft.com/en-us/library/hh409293%28v=vs.110%29.aspx and http://blogs.msdn.com/b/vcblog/archive/2011/09/12/10209291.aspx – Fraser Apr 18 '12 at 02:16
  • Damn, we're not even getting the default move constructor generation for the final VS11 release :/ – Trillian Apr 18 '12 at 11:53