为啥 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
(与类型无关)。
使PageProvider
对Processor
的继承成为非虚拟的。
在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 会给出不同的答案
为啥这个结构文字在 VS2013 中通过地址而不是 gcc/clang 时会损坏?