Clang编译工作,而gcc不用于钻石继承

Mar*_* A. 10 c++ inheritance gcc clang c++11

我不确定我是否在这里遗漏了一些东西,但似乎下面的代码(类似的代码可以找到我再也找不到的另一个答案,这里的问题是不同的)编译就好了铿锵不是为gcc编译

#include <iostream>
using namespace std;

class base {
public:
 base(int i) {};

private:
 base(){};
};

class derivedA: virtual public base {
public:
 derivedA(int i) : base(i) {};

protected:
  derivedA() : base(0) {};
};

class derivedB: virtual public base {
public:
 derivedB(int i) : base(i) {};

protected:
  derivedB() : base(0) {};
};

class derivedAB : public derivedA, public derivedB {
public:
 derivedAB(int i) {};
 virtual ~derivedAB() = 0;
};

derivedAB::~derivedAB() {};

class lastDerived : public derivedAB {
public:
    lastDerived() : base(1), derivedAB(0) {};
};

int main(){
        lastDerived obj;
}
Run Code Online (Sandbox Code Playgroud)

gcc正在报道

main.cpp: In constructor 'derivedAB::derivedAB(int)':
main.cpp:9:2: error: 'base::base()' is private
  base(){};
Run Code Online (Sandbox Code Playgroud)

哪一个是正确的行为?我会说gcc是一个,但我不确定为什么.

eca*_*mur 12

抽象类的虚基类不需要在该抽象基类的构造函数的mem-initializer-list初始化.

这将在12.6.2p8中讨论:

[...]并且实体不是抽象类的虚拟基类[...]
[ 注意:抽象类(10.4)永远不是最派生的类,因此它的构造函数永远不会初始化虚拟基类,因此可以省略相应的mem初始化器.- 结束说明 ]

所以clang是正确的,gcc是不正确的.这将是不同的derivedAB不抽象.


DR 257以来,这是C++ 11中的新容差; g ++对于C++ 03是正确的.https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19249上有一个gcc错误; 也许它可以用戳戳.