The following code seems to run fine when compiled with clang or gcc (on macOS), but crashes when compiled with MS Visual C++ 2017. On the latter, the foo_clone object appears to be corrupted and the program crashes with an access violation on the line foo_clone->get_identifier().
It does work on VC++ if I remove the covariant return types (all clone-methods return IDO*), or when std::enable_shared_from_this is removed, or when all inheritance is made virtual.
Why does it work with clang/gcc but not with VC++?
#include <memory>
#include <iostream>
class IDO {
public:
virtual ~IDO() = default;
virtual const char* get_identifier() const = 0;
virtual IDO* clone() const = 0;
};
class DO
: public virtual IDO
, public std::enable_shared_from_this<DO>
{
public:
const char* get_identifier() const override { return "ok"; }
};
class D : public virtual IDO, public DO {
D* clone() const override {
return nullptr;
}
};
class IA : public virtual IDO {};
class Foo : public IA, public D {
public:
Foo* clone() const override {
return new Foo();
}
};
int main(int argc, char* argv[]) {
Foo* foo = new Foo();
Foo* foo_clone = foo->clone();
foo_clone->get_identifier();
}
Message:
Exception thrown at 0x00007FF60940180B in foo.exe: 0xC0000005: Access violation reading location 0x0000000000000004.