2016-11-04 49 views
1

我看到鏗鏘3.8.0和gcc 6.2.1處理我認爲是有效的代碼的一些差異。下面是一個例子,其clang++ --std=c++11 vitest.cpp編譯沒有評論:爲什麼clang和gcc不同意這個虛擬繼承代碼?

#include <iostream> 

class Processor { 
public: 
    Processor(int i, float f) {} 

    virtual ~Processor() noexcept {} 

    virtual void getStatistics() = 0; 
}; 

class PageProvider : virtual public Processor { 
public: 
    PageProvider(int i, float f) 
//  : Processor{i,f} // Without this, GCC wants to call default ctor 
    {} 

    virtual ~PageProvider() {} 
}; 

class QuotePageProvider : public PageProvider { 
public: 
    QuotePageProvider(int i, float f) 
     : Processor{i,f}, 
      PageProvider{i,f} 
    {} 

    virtual void getStatistics() { std::cout << "Hi there" << std::endl; }; 
}; 

int main(int argc, char* argv[]) 
{ 
    PageProvider* prov2{new QuotePageProvider{1,2.2}}; 
    prov2->getStatistics(); 
    delete prov2; 
} 

第一異常是克++(具有相同的命令行參數)抱怨有PageProvider構造:

vitest.cpp:16:2: error: no matching function for call to ‘Processor::Processor()’ 

這可以得到解決通過取消註釋處理器的顯式初始化,如上所示。根據下面的aschepler's answer,這是一個已知的gcc錯誤。

已經免除的是,事情變得更有趣:

vitest.cpp: In constructor ‘QuotePageProvider::QuotePageProvider(int, float)’: 
vitest.cpp:25:20: error: cannot allocate an object of abstract type ‘PageProvider’ 
    PageProvider{i,f} 
        ^
vitest.cpp:12:7: note: because the following virtual functions are pure within ‘PageProvider’: 
class PageProvider : virtual public Processor { 
     ^~~~~~~~~~~~ 
vitest.cpp:9:15: note: virtual void Processor::getStatistics() 
    virtual void getStatistics() = 0; 
       ^~~~~~~~~~~~~ 

看來,GCC堅持以編譯QuotePageProvider有getStatistics的實現()在PageProvider提供,而鐺沒有。我收到了編譯with gcc 5.1的相同結果。

我可以說服的gcc通過執行以下任一的編譯的代碼:

  • 減少參數的數量來PageProvider的構造1 (不考慮類型的)。
  • 使的的繼承非虛擬。
  • QuotePageProvider的構造函數初始化列表中,將PageProvider的初始化更改爲使用括號而不是curlies。緊接在上面的Processor的初始化的類似改變沒有效果。

這可能是兩個編譯器解釋不同的標準中的一些奇怪的角落案例,還是其中一個被破壞?

+0

下半部分是另一個GCC bug。 (好吧,這是標準IIRC中的一個bug,已經實施到信中,然後標準得到修復,然後GCC得到修復,但不完全。) –

+0

https://gcc.gnu.org/bugzilla/show_bug .cgi?id = 65615 –

+0

@TC賓果,這看起來是完全它。如果您想將您的評論升級爲答案,我會接受它。 –

回答

4

這是gcc bug 53878

抽象類不應該需要構造它的虛擬基類。

+0

感謝您的參考,但這似乎只是問題的第一部分。如果PageProvider明確初始化處理器,這似乎解決了您引用的錯誤,但仍存在編譯器希望實現getStatistics()的問題。或者你是說他們有某種相關性? –