0

I have a class where VS 2015 was not generating a move ctor and now VS 2015 Update 1 it is generating one, this is causing a binary compatibility issue, not sure which version is doing the right thing.

// MyLib
struct Shared
{
   virtual ~Shared(){}
}

struct Callback : public Shared
{
    virtual void response() = 0;
}

// App
struct CallbackI : public Callback
{
   virtual void response(){}
}

When I build MyLib with VS 2015 and App with VS 2015 update 1 linking App fails because a missing symbol referencing the move assignment operator for Callback base class.

Seems to me that VS 2015 is not generating this operators and VS 2015 Update 1 it is, but which compiler version is right here?

José
  • 3,041
  • 8
  • 37
  • 58

1 Answers1

3

VS 2015 Update 1 is doing the right thing (and actually the first VS version that implements all of C++11)

From the standard:

§12.8 Copying and moving class objects

If the definition of a class X does not explicitly declare a move constructor, one will be implicitly declared as defaulted if and only if

  • X does not have a user-declared copy constructor,
  • X does not have a user-declared copy assignment operator,
  • X does not have a user-declared move assignment operator,
  • X does not have a user-declared destructor, and
  • the move constructor would not be implicitly defined as deleted.

The user-generated destructor in Shared implicitly marks the move constructor as deleted. When you let the compiler generate it, the compiler can also generate the move assignment operator.

struct Shared
{
   virtual ~Shared() = default;
}

For performance reasons, it's also better to declare empty virtual destructors this way because it guarantees inlining by the compiler.

jupp0r
  • 4,502
  • 1
  • 27
  • 34
  • My understanding is that Shared having a user defined destructor prevents the move assignment and move constructors from being generated, and so the derived types will not have one. – José Jan 15 '16 at 13:05
  • in other words "T has direct or virtual base class that cannot be move-assigned (has deleted, inaccessible, or ambiguous move assignment operator);" http://en.cppreference.com/w/cpp/language/move_assignment – José Jan 15 '16 at 13:09
  • IMO vs 2015 Update 1 is wrong as the user defined destructor in Shared should prevent the move assignment operator being generated, and that should affect Callback derived class as it has a virtual base class that has a deleted move assignment operator. – José Jan 15 '16 at 13:57