首页 > 解决方案 > 什么时候调用 constinit 对象的析构函数?

问题描述

一般来说,静态对象的析构函数的调用顺序与构造函数的相反。据我了解, constinit 对象是在编译时初始化的,因此应该在“普通”静态对象的析构函数之后调用它们的析构函数。

该程序

struct A
{
  constexpr A(const char* t): t_(t) {}
  ~A() {std::cout << "~A(" << t_ << ")\n";} 
  const char* t_;
};  

static A a1("static");  

int main () {
   static constinit A a2("constinit");  
   return 0;
} 

(使用 GCC 10),但是,给出了输出

~A(constinit)
~A(static)

即 constinit 对象在“正常”静态对象之前被销毁(尽管它是较早构造的)。“逆序”规则对 constinit 对象不再有效吗?

标签: c++destructorc++20initialization-orderconstinit

解决方案


两者a1a2都是常量初始化的。说明constinit符仅断言被定义的变量是常量初始化的。所以这里a1在之前被初始化,a2所以在预期之前a2被销毁。a1

“逆序”规则对constinit对象不再有效吗?常量初始化对象和动态初始化对象之间没有相反的顺序规则:即使常量初始化对象的构造发生在动态初始化对象的构造之前,常量初始化对象的销毁也是按顺序进行的,就好像它们已经动态初始化一样:[basic.start.术语]/3

如果对象是静态初始化的,则对象的销毁顺序与动态初始化对象的顺序相同。


推荐阅读