2013-05-31 77 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; 
} 

我有這樣的代碼。它可以在Ubuntu 12.10和13.04下的Windows 8,g ++ 4.7和Clang ++ 3.2(包括x86和x64)下按預期運行MSVC 2012 x64。但是,帶有問號的行在使用MinGW 4.7 x86 或MinGW 4.8 x64(對不起,我以爲我做過)編譯時演示了未定義的行爲。這是鑽石繼承UB在MinGW中的錯誤?

調試器輸出表示在此時鏈接到TargetClass的vtable時出現問題。放置斷點表明TargetClass :: operator string()被加載了嚴重的解除引用的對象。但是,將顯式dynamic_cast置於正確的輸出。

我不知道什麼可能會導致這個問題。如果它是MinGW的一個bug,它一出現就可能被解決,因爲它破壞了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十一月CTP
  • 32位鏘3.2使用GCC 4.6的libstdC++

所有在Windows,所有給出的輸出:

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

這與Linux上的Clang和GCC相同。

這是不確定的行爲與否,我不確定。從未使用過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