I'm experiencing an error using g -12 which does not occur in clang -13. In particular, this code:
struct A{
constexpr virtual ~A() = default;
constexpr A() = default;
};
struct B : public A {
constexpr ~B() = default;
constexpr B() = default;
};
constexpr int demo(){
B *b = new B();
delete b;
return 2;
}
int main(){
constexpr int demod = demo();
return demod;
}
Compiles with clang , but with g gives the error:
minimize-error.cpp: In function ‘int main()’:
minimize-error.cpp:18:31: in ‘constexpr’ expansion of ‘demo()’
minimize-error.cpp:13:12: error: ‘virtual constexpr B::~B()’ used before its definition
13 | delete b;
|
Curiously, if I just remove the constexpr
requirement on demod
, the example compiles and runs without error.
Any ideas as to what's happening here?
CodePudding user response:
It is a GCC bug, see this report.
Virtual defaulted destructors don't seem to work at all in constant evaluation with current GCC. As also mentioned in the bug report, simply
struct A{
constexpr virtual ~A() = default;
};
constexpr A a;
also fails.
As a workaround you can provide definitions for the destructors manually instead of defaulting:
constexpr virtual ~A() {}
/*...*/
constexpr ~B() {}
Then GCC seems happy.
CodePudding user response:
As the commenters indicated, this is an instance of bug 93413. The duplicate bug 104653 suggests a workaround:
struct A{
constexpr virtual ~A() = default;
constexpr A() = default;
};
struct B : public A {
virtual constexpr ~B() override;
constexpr B() = default;
};
constexpr B::~B() = default;
consteval int demo(){
B *b = new B();
delete b;
return 2;
}
int main(){
return demo();
}