Is this inheritance of UB diamonds a mistake in MinGW?

#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 on Windows 8, g ++ 4.7, and Clang ++ 3.2 (both x86 and x64) on Ubuntu 12.10 and 13.04. However, the line with question marks shows undefined behavior when compiling with MinGW 4.7 x86 or MinGW 4.8 x64 (sorry, I thought I did).

The debugger output indicates that there is a problem with binding to the vtable TargetClass at this point. Placing breakpoints indicates that TargetClass :: operator string () loads with a highly dereferenced object. However, using explicit dynamic_cast makes the right conclusion.

I wonder what might cause this problem. If it was a MinGW error, it would probably be resolved as soon as it appeared, because it violates one of the basic concepts of C ++.

+4
source share
3 answers

This is a known issue with mingw gcc.

Do not use virtual inheritance and the problem goes away.

Bugtracker http://sourceforge.net/p/mingw/bugs/1679/

+4
source

It looks like a compiler error (or a runtime error for dynamic_cast ). The code looks right, although I didn’t dig it through carefully. Unless, of course, the published code is the code that creates the problem.

+1
source

I just checked:

  • 32-bit and 64-bit builds MinGW-w64 GCC 4.6 / 4.7 / 4.8
  • MSVC 11.0 and MSVC November 11.0 CTP
  • 32-bit Clang 3.2 using GCC 4.6 libstdc ++

everything on Windows, and everyone gives the output:

 1 2 3 4 1 2 3 4 1 2 3 4 

which is the same as Clang and GCC in Linux.

Whether this is undefined behavior or not, I'm not sure. Dynamic_cast is never used.

+1
source

Source: https://habr.com/ru/post/1483875/


All Articles