Home > other >  constexpr C errorr: destructor used before its definition
constexpr C errorr: destructor used before its definition

Time:07-02

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();
}
  • Related