簡體   English   中英

這個鑽石繼承UB是MinGW中的錯誤嗎?

[英]Is this diamond inheritance UB a bug 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;
}

我有這樣的代碼。 它可以在Windows 8,g ++ 4.7和Windows 12.10和13.04下的Clang ++ 3.2(x86和x64)下與MSVC 2012 x64一起正常工作。 但是,用MinGW 4.7 x86編譯時,帶有問號的行演示未定義的行為 或MinGW 4.8 x64 (對不起,我以為是)。

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

我想知道什么可能導致這個問題。 如果它是MinGW的錯誤,則可能會盡快解決,因為它破壞了C ++的核心概念之一。

這是mingw gcc的已知問題。

不要使用虛擬繼承,問題就消失了。

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

這看起來像是編譯器錯誤(或dynamic_cast的運行時支持中的錯誤)。 該代碼看起來正確,盡管我沒有仔細研究它。 當然,除非發布的代碼不是產生問題的代碼。

我剛剛測試過:

  • 32位和64位MinGW-w64 GCC 4.6 / 4.7 / 4.8構建
  • MSVC 11.0和MSVC 11.0 11月CTP
  • 使用GCC 4.6 libstdc ++的32位Clang 3.2

全部在Windows上,並提供輸出:

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

與Linux上的Clang和GCC相同。

我不確定這是否是未定義的行為。 從未使用dynamic_cast

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM