【问题标题】: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 )
//      : 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;
}

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

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

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

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

【问题讨论】:

  • 后半部分是另一个 GCC 错误。 (嗯,这是标准 IIRC 中的一个错误,它被严格执行,然后标准得到修复,然后 GCC 得到修复,但不完全。)
  • @T.C.宾果游戏,看起来就是这样。如果您想将您的 cmets 升级为答案,我会接受。

标签: c++ c++11 g++ clang++


【解决方案1】:

这是 gcc 错误53878

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

【讨论】:

  • 感谢您的参考,但这似乎只是问题的第一部分。如果 PageProvider 显式初始化处理器,这似乎可以解决您引用的错误,但仍然存在编译器想要实现 getStatistics() 的问题。还是说它们有某种关联?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-26
  • 2020-10-16
  • 2021-05-28
  • 1970-01-01
  • 1970-01-01
  • 2020-10-30
相关资源
最近更新 更多