#include <iostream>
#include <sstream>
class VeryBase {
protected:
int a_;
public:
VeryBase() : a_(1) {}
virtual operator std::string() {
return "0";
}
};
class Base1 : public virtual VeryBase {
protected:
int b_;
public:
Base1() : b_(2) {}
operator std::string() {
return "1";
}
};
class Base2 : public virtual VeryBase {
protected:
int c_;
public:
Base2() : c_(3) {}
operator std::string() {
return "2";
}
};
class TargetClass : public Base1, public Base2 {
protected:
int d_;
public:
TargetClass() : d_(4) {}
operator std::string() {
std::ostringstream s;
s << a_ << ' ' << b_ << ' ' << c_ << ' ' << d_ << std::endl;
return s.str();
}
};
int main()
{
VeryBase* a = new TargetClass;
Base1* b = dynamic_cast<Base1*>(a);
Base2* c = dynamic_cast<Base2*>(a);
std::cout << std::string(*a) //1 2 3 4
<< std::string(*b) //1 2 3 4
<< std::string(*c) //? ? ? ?
<< std::endl;
}
I have a code like this. It works as expected with MSVC 2012 x64 under Windows 8, g++ 4.7 and Clang++ 3.2 (both x86 and x64) under Ubuntu 12.10 and 13.04. However, line with question marks demonstrates undefined behavior when compiled with MinGW 4.7 x86 or MinGW 4.8 x64 (sorry, I thought I did).
Debugger output says that there is a problem with linking to vtable of TargetClass at that point. Placing breakpoints shows that TargetClass::operator string() is loaded with badly dereferenced object. Putting explicit dynamic_cast, however, makes right output.
I wonder what can possibly cause this problem. If it was a bug of MinGW, it would probably be solved as soon as it appeared, because it breaks one of the core concepts of C++.