代码不能在 g++ 中编译,而在 clang++ 中编译

Posted

技术标签:

【中文标题】代码不能在 g++ 中编译,而在 clang++ 中编译【英文标题】:code does not compile in g++ while it does in clang++ 【发布时间】:2016-10-28 15:14:57 【问题描述】:

所以我有这个非常短的代码:

test.cpp

class Base 
    public:
        Base(int i) ;
;

class Child : public virtual Base 
    using Base::Base;
;

int main(int argc, char * argv[]) 
    auto *child = new Child(1);
    return 0;
;

在clang++(3.8.0)下编译良好:

$ clang++ test.cpp -std=c++11

虽然在 g++ (5.4.0) 下失败:

$ g++ test.cpp -std=c++11
test.cpp: In function ‘int main(int, char**)’:
test.cpp:14:30: error: use of deleted function ‘Child::Child(int)’
     auto *child = new Child(1);
                              ^
test.cpp:8:17: note: ‘Child::Child(int)’ is implicitly deleted because the default definition would be ill-formed:
     using Base::Base;
                 ^
test.cpp:8:17: error: no matching function for call to ‘Base::Base()’
test.cpp:3:9: note: candidate: Base::Base(int)
         Base(int i) ;
         ^
test.cpp:3:9: note:   candidate expects 1 argument, 0 provided
test.cpp:1:7: note: candidate: constexpr Base::Base(const Base&)
 class Base 
       ^
test.cpp:1:7: note:   candidate expects 1 argument, 0 provided
test.cpp:1:7: note: candidate: constexpr Base::Base(Base&&)
test.cpp:1:7: note:   candidate expects 1 argument, 0 provided

出于某种原因,g++ 期望 Base 类具有默认构造函数。这是为什么呢?

编辑:这也无法复制。这段代码:

auto child = Child(1);

在 g++ 下产生同样的错误,而这个:

Child child(1);

工作正常。但我还是不明白为什么?

编辑 2: 如果没有 virtual 关键字,它在两种编译器下都能正常工作。

【问题讨论】:

有趣。如果您删除 Child 的 virtual 继承,或者如果您为 Child 显式定义构造函数:Child(int i) : Base(i) ,则会编译。 【参考方案1】:

我认为这是一个 g++ 错误。

来自N2540,我强调:

通常,为具有虚拟基的类继承构造函数定义将是格式错误的,除非虚拟基支持默认初始化,或者虚拟基是直接基,并命名为base forwarded-to。 同样,所有数据成员和其他直接基必须支持默认初始化,否则任何使用继承构造函数的尝试都将是错误的。注意:使用时格式错误,未声明。

据我所知,你的例子完全符合我强调的条件,所以我认为它应该有效。但请注意,这是一份工作草案变更提案;在纳入最终标准之前,它可能已经改变。但我希望如果有任何变化,它可能会允许更多案件,而不是禁止更多案件。

也许可以访问实际标准的人可以仔细检查。

【讨论】:

以上是关于代码不能在 g++ 中编译,而在 clang++ 中编译的主要内容,如果未能解决你的问题,请参考以下文章

g++、clang++、使用libboost的编译花絮——g++7成功时g++8编译失败;

用 g++ 编译的奇怪代码

使用 clang-cl 用 openmp 编译 C 代码

如何在 Qt creator 中更改/配置所需的编译器?即在 MSVC/Mingw 或 g++/clang++ 之间切换

VSCode编写C++后不能编译运行

自动模板参数:g ++ 7.3 vs clang ++ 6.0:哪个编译器正确?