I have encountered what appears to me to be a corrupted virtual table that results from building and running the example code posted below in Visual Studio 2015.
When I run it, an exception is thrown when m_string has been assigned.
I have verified that the code builds and runs as intended using both gcc and Clang compilers.
I tried to make the example as minimal as possible, as it was synthesized down from a very large project.
Also, I realize that I am returning null from some of the functions - the actual return value isn't relevant to the problem, but the return type may be. Is this a possible Visual Studio bug?
#include <iostream>
#include <memory>
#include <string>
struct A { virtual ~A(void) { } };
struct B { virtual ~B(void) { } };
struct C : public A, public B { virtual ~C(void) override { } };
struct D
{
virtual ~D(void) { }
virtual B *func(void) = 0;
};
struct E : public D
{
virtual ~E(void) override { }
virtual C *func(void) override { return nullptr; }
};
struct F : public A, public E
{
virtual ~F(void) override { }
C *func(void) override
{
m_string = "Why does the act of setting this field cause a crash?";
return nullptr;
}
std::string m_string;
};
int main(int argc, char **argv)
{
std::unique_ptr<F> pF(new F());
(dynamic_cast<D *>(pF.get()))->func();
pF->func();
return 0;
}
A solution is to make inheritance from class A virtual.
struct C : virtual public A, public B { virtual ~C(void) override { } };
or
struct F : virtual public A, public E { ... }
The problem is most probably related to the virtual desctructors in the base classes. Maybe others can provided more explanation why this works.
As pointed out by @JamesAdkison swapping inherited classes (changing struct C : public A, public B {...}
to struct C : public B, public A {...}
) resolves the issue too; so does changing struct F : public A, public E { ... }
to struct F : public E, public A { ... }
. So, it seems like a bug in MSVC, as mentioned by @Josh P.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With