为啥 clang 和 gcc 在这个虚拟继承代码上存在分歧?

Posted

技术标签:

【中文标题】为啥 clang 和 gcc 在这个虚拟继承代码上存在分歧?【英文标题】:Why do clang and gcc disagree on this virtual inheritance code?为什么 clang 和 gcc 在这个虚拟继承代码上存在分歧? 【发布时间】:2016-11-04 21:18:32 【问题描述】:

我发现 clang 3.8.0 和 gcc 6.2.1 处理我认为是有效代码的方式存在一些差异。这是一个示例,clang++ --std=c++11 vitest.cpp 编译时没有注释:

#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 )
//      : Processori,f    // Without this, GCC wants to call default ctor
    

    virtual ~PageProvider() 
;

class QuotePageProvider : public PageProvider 
public:
    QuotePageProvider( int i, float f )
        : Processori,f,
            PageProvideri,f
    

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

int main( int argc, char* argv[] )

    PageProvider*   prov2new QuotePageProvider1,2.2;
    prov2->getStatistics();
    delete prov2;

第一个异常是 g++(使用相同的命令行参数)抱怨 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’
    PageProvideri,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 似乎坚持在PageProvider 中提供getStatistics() 的实现,以便编译QuotePageProvider,而clang 没有。我在编译with gcc 5.1 时得到了相同的结果。

我可以说服 gcc 通过执行以下任何操作来编译代码:

PageProvider的构造函数的参数数量减少到1 (与类型无关)。 使PageProviderProcessor 的继承成为非虚拟的。 在QuotePageProvider 的构造函数的初始化列表中,将PageProvider 的初始化更改为使用括号而不是花括号。对上面Processor 的初始化进行类似的更改没有效果。

这可能是标准中的一些奇怪的极端情况,两个编译器的解释不同,还是其中一个被破坏了?

【问题讨论】:

后半部分是另一个 GCC 错误。 (嗯,这是标准 IIRC 中的一个错误,它被严格执行,然后标准得到修复,然后 GCC 得到修复,但不完全。) gcc.gnu.org/bugzilla/show_bug.cgi?id=65615 @T.C.宾果游戏,看起来就是这样。如果您想将您的 cmets 升级为答案,我会接受。 【参考方案1】:

这是 gcc 错误53878。

抽象类不需要构造它的虚拟基类。

【讨论】:

感谢您的参考,但这似乎只是问题的第一部分。如果 PageProvider 显式初始化处理器,这似乎可以解决您引用的错误,但仍然存在编译器想要实现 getStatistics() 的问题。还是说它们有某种关联?

以上是关于为啥 clang 和 gcc 在这个虚拟继承代码上存在分歧?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 gcc 和 clang 上通过优化将大 double 转换为 uint16_t 会给出不同的答案

为啥 gcc 会产生这个奇怪的程序集 vs clang?

为啥这个结构文字在 VS2013 中通过地址而不是 gcc/clang 时会损坏?

为啥以下代码使用clang而不是gcc编译

为啥 gcc -O3 处理 avx256 的内在比较与 gcc -O0 和 clang 不同?

为啥这段代码不能用 clang 构建,用 gcc 崩溃,但用 VC++ 运行良好? [复制]