Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

corrupted virtual table visual studio bug

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;
}
like image 671
Josh Parker Avatar asked May 04 '16 15:05

Josh Parker


1 Answers

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.

like image 107
Eissa N. Avatar answered Oct 26 '22 12:10

Eissa N.