2013-05-31 2 views
4
#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; 
} 

У меня есть такой код. Он работает как ожидается с MSVC 2012 x64 под Windows 8, g ++ 4.7 и Clang ++ 3.2 (как x86, так и x64) в Ubuntu 12.10 и 13.04. Однако строка с вопросительными знаками демонстрирует неопределенное поведение при компиляции с MinGW 4.7 x86 или MinGW 4.8 x64 (извините, я думал, что сделал).Является ли это наследование алмазов UB ошибкой в ​​MinGW?

Выход отладчика говорит о наличии проблемы с привязкой к vtable TargetClass в этой точке. Размещение точек останова показывает, что TargetClass :: operator string() загружается с сильно разыменованным объектом. Однако использование явного dynamic_cast делает правильный вывод.

Интересно, что может вызвать эту проблему. Если бы это была ошибка MinGW, она, вероятно, была бы решена, как только она появилась, потому что она нарушает одну из основных концепций C++.

+5

«Неопределенное поведение» представляет собой технический термин в определении языка. Это означает ** только **, что в определении языка не говорится, что происходит. Если вы видите странные вещи, когда вы запускаете свой код, это не обязательно «демонстрирует неопределенное поведение». –

+1

Формально код нуждается в '#include ' где-то наверху. Вероятно, это не связано с проблемой. –

ответ

1

Это похоже на ошибку компилятора (или ошибку в поддержке времени выполнения для dynamic_cast). Код выглядит правильно, хотя я не прорыл его тщательно. Если, конечно, размещенный код не является кодом, который создает проблему.

1

Я только протестированы с:

  • 32-х и 64-битный MinGW-w64 GCC 4.6/4.7/4.8 сборки
  • MSVC 11,0 и MSVC 11,0 ноября СТР
  • 32-битный Clang 3,2 с использованием GCC 4.6 libstdC++

все на Windows, и все дает выход:

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

, который аналогичен Clang и GCC на Linux.

Является ли это неопределенным поведением или нет, я не уверен. Никогда не используется dynamic_cast.

+0

Спасибо за это. Интересно, у меня сломанная сборка с Qt-пакетом. – isCasted

+0

...... У вас есть ссылка? – rubenvb

+0

Я думаю, что это одно: http://download.qt-project.org/official_releases/qt/5.0/5.0.1/qt-windows-opensource-5.0.1-mingw47_32-x86-offline.exe – isCasted