代码之家  ›  专栏  ›  技术社区  ›  Mae Milano

constexpr C++error:在其定义之前使用析构函数

  •  5
  • Mae Milano  · 技术社区  · 2 年前

    我在使用g++-12时遇到了一个错误,而在clang++-13中没有出现这个错误。特别是,该代码:

    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;
    }
    

    使用clang++编译,但使用g++会出现错误:

    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;
          |
    

    奇怪的是,如果我删除 constexpr 对的要求 demod ,示例编译并运行时没有出错。

    你知道这里发生了什么吗?

    2 回复  |  直到 2 年前
        1
  •  4
  •   user17732522    2 年前

    this report .

    在当前GCC的常量求值中,虚拟默认析构函数似乎根本不起作用。正如bug报告中所提到的,简单地说

    struct A{
        constexpr virtual ~A() = default;
    };
    
    constexpr A a;
    

    也失败了。

    作为一种解决方法,您可以手动提供析构函数的定义,而不是默认定义:

    constexpr virtual ~A() {}
    
    /*...*/
    
    constexpr ~B() {}
    

    然后GCC似乎很高兴。

        2
  •  2
  •   Mae Milano    2 年前

    正如评论者所指出的,这是一个bug实例 93413 . 重复错误 104653 建议解决方法:

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