Question Details

No question body available.

Tags

c++ compiler-warnings virtual-inheritance move-assignment-operator defaulted-functions

Answers (1)

July 3, 2026 Score: 1 Rep: 496,024 Quality: Medium Completeness: 80%

[...] only in cases the compiler can notice the situation and avoid naively invoking the B and C move assignment.

The problem is that D doesn't have any real alternative to the B and C move assignments. In theory, it might be able to copy one, and then move the other, but only if at least one of them is also copyable (which isn't guaranteed). But that also has the potential of being fairly expensive, for little or no good reason.

To really do the job well, you'd like B and C to have something like a moveexclusvie that moved only their own sub-part of whatever overall object was involved.

If such a thing existed, D could synthesize a move assignment something like:

newobject.Asubpart = std::move(oldobject.Asubpart);
newobject.Bsubpart = moveexclusive(oldobject.Bsubpart);
newobject.Csubpart = moveexclusive(oldobject.Csubpart);

But, since D has no access to anything like this moveexclusive, all it can do is (as you stated it), naively invoke the B and C assignment, and hope that somehow or other, that doesn't try to move out of the A subpart more than once.

In theory, if you could be sure that you always had the source code to B and C when you were compiling D, you could basically re-compile the source to their operators (leaving out any code injected to deal with the base class), and be able to create a correct move assignment operator independently. With enough care, you might be able to make that work with sepatate compilation, but my immediate guess is that it would be quite a lot of work to solve a fairly unusual problem.

That said, if (for example) A has remote ownership of any data, you'll typically want it to assure against a double-move, rather than B or C doing so. In that respect, I'd consider the warning message somewhat misleading.

In this regard, Clang does somewhat better, so it'll usually emit a warning like:

warning: defaulted move assignment operator of 'D' will move
      assign virtual base class 'A' multiple times [-Wmultiple-move-vbase]

...which may not be perfect, but at least to me seems a bit more helpful and less noisy than gcc's.

It's also true that gcc is (or at least in some versions was) known to issue this warning in a few cases where it's not strictly applicable, such as:

class A {}:
class B : virtual public A {};
class C : public B {};

gcc seems to kind of take for granted (somewhat reaonably) that since B inherits virtually from A, the most derived class will use multiple inheritance. In this case there's no multiple inheritance, but (at least some versions of) gcc will still emit a warning about it.

Clang seems to do a bit better in this case as well (doesn't emit a warning for code like example).

Reference

For what it's worth, an older question/answer about cases where gcc issues this warning, when it's not really applicable:

Why does gcc warn about calling a non-trivial move assignment operator with std::tuple and virtual inheritance?