8

I appreciate the C++11 standard dictates:

If the class definition does not explicitly declare a copy constructor, one is declared implicitly. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy constructor is defined as deleted; otherwise, it is defined as defaulted.

(actually copied from here)

The following code:

#include <iostream>

struct C
{
    int x = 1;

    C()
    {
    }

    C(C&&)
    {
    }
};

int main()
{
    const C c;
    C c2(c);

    std::cout << c.x << " " << c2.x << std::endl;

    return 0;
}

does not compile on gcc 4.9.0, but compiles just fine on Visual Studio 2013 (Compiler Version 18.00.21005.1 for x86). Is this yet another Visual Studio violation of the standard, or am I doing something wrong this time? If this is a violation of the standard, is there a tracking bug or any source where this behaviour is documented?

Community
  • 1
  • 1
gd1
  • 11,300
  • 7
  • 49
  • 88
  • Can you post the compilation error message(s) ? Would be useful... – floppy12 May 08 '15 at 10:02
  • @floppy12 : http://ideone.com/yhqPBb That's gcc 4.9.2 in c++14 mode. Your gcc will probably do the same. Anyway it's not the presence of an error with gcc the problem, but its absence with VS. – gd1 May 08 '15 at 10:10

1 Answers1

5

You're not doing anything wrong, and your interpretation of the standard is correct. Visual C++ 2013 indeed does not implement these rules properly.

A relevant bug report is here:

Default copy constructor is generated even when a custom move constructor is defined [c++11]

It's marked as Won't Fix and the comment from the development team is:

Visual Studio 2013 indeed does not fully implement the C++11 rules governing special member functions and move operations. We will include a fix for this bug in the next major release of Visual Studio.

The good news is that things seem to be working properly in Visual C++ 2015 RC. I've just verified that your code triggers both compiler and IntelliSense errors. The compiler diagnostic is:

error C2280: 'C::C(const C &)': attempting to reference a deleted function

(From what I've tested during the past few months, MSVC14 is shaping up as a pretty good C++ compiler - lots of standard compliance issues have been fixed.)

bogdan
  • 9,229
  • 2
  • 33
  • 48
  • That's indeed good news *for the future*, but for the present it's a hell of a problem. If you have to break the standard, I am fine if you do it by not providing the functionality X or Y, but if you provide half of it, you can put entire projects in severe jeopardy. A copy happening my mistake could be a disaster. – gd1 May 08 '15 at 11:34
  • 1
    @gd1 Yeah, I feel your pain. However, in places where preventing copies is so important that it could make or break the project, I'd say it's a good idea to explicitly `= delete` the copy constructor (and probably the copy assignment operator too) anyway. That's what I'm doing so far in Visual C++ 2013, and this part works fine. – bogdan May 08 '15 at 11:41