c++ - 什么时候调用 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 对象不再有效吗?
解决方案
两者a1
和a2
都是常量初始化的。说明constinit
符仅断言被定义的变量是常量初始化的。所以这里a1
在之前被初始化,a2
所以在预期之前a2
被销毁。a1
“逆序”规则对constinit
对象不再有效吗?常量初始化对象和动态初始化对象之间没有相反的顺序规则:即使常量初始化对象的构造发生在动态初始化对象的构造之前,常量初始化对象的销毁也是按顺序进行的,就好像它们已经动态初始化一样:[basic.start.术语]/3
如果对象是静态初始化的,则对象的销毁顺序与动态初始化对象的顺序相同。
推荐阅读
- python - 使用 numpy.apply_along_axis 时提高代码速度
- c# - 如何在 n 层架构应用程序中注册依赖注入
- r - 在循环中过滤 spark tbl
- abap - 智能表单中的语法错误“字段“L_TABDEF–TLTYPE”未知”
- netsuite - Freemarker 和 SuiteScript 呈现的高级 PDF - 替换字段中的双连字符
- javascript - 尝试在点击事件上绑定 openlayers 地图时出错
- ruby-on-rails - 如何跳过重新生成安全令牌的验证
- javascript - 用css计算小宽度的边框半径
- kubernetes - kubenetes - greeter-web 调用 greeter-srv 500 错误?
- jquery - jQuery - 清除更改函数中的输入