Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

constexpr C++ error: destructor used before its definition

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?

like image 249
Mae Milano Avatar asked Dec 04 '25 17:12

Mae Milano


2 Answers

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.

like image 142
user17732522 Avatar answered Dec 06 '25 06:12

user17732522


As it turns out, there's a workaround to make Virtual defaulted destructors work in constant evaluation with current GCC! As StoryTeller indicated in a comment, 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();
}
like image 27
Mae Milano Avatar answered Dec 06 '25 08:12

Mae Milano