gpt4 book ai didi

c++ - 静态初始化的非文字对象的销毁顺序

转载 作者:可可西里 更新时间:2023-11-01 16:17:50 28 4
gpt4 key购买 nike

A recent question提请我注意 constexpr has changed in C++14 的方式.新特性是,如果其初始化程序由 constexpr 构造函数组成,则具有静态存储持续时间的非局部变量可以在静态初始化阶段进行初始化,即使变量的类型不是文字类型。更准确地说,[basic.start.init] 中的新措辞是:

A constant initializer for an object o is an expression that is a constant expression, except that it may also invoke constexpr constructors for o and its subobjects even if those objects are of non-literal class types [Note: such a class may have a non-trivial destructor — end note]. Constant initialization is performed [...] if an object with static or thread storage duration is initialized by a constructor call, and if the initialization full-expression is a constant initializer for the object [...]

典型的例子是std::unique_ptr,它“应该永远不会比手写的差”:

std::unique_ptr<int> p;   // statically initialized by [unique.ptr.single.ctor],
// requires no code excution
int main()
{
p = std::make_unique<int>(100);
}

// p is destroyed eventually

在此添加之前,静态初始化的变量要么是引用类型,要么是文字对象类型,因此具有平凡的析构函数。但是现在静态初始化的全局变量可以有一个非平凡的析构函数。

这样的析构函数调用对于动态初始化的全局对象的析构函数是如何排序的,相对于其他静态初始化的对象,以及析构函数调用是如何排序的?

最佳答案

考虑

If an object is initialized statically, the object is destroyed in the same order as if the object was dynamically initialized.

If the completion of the constructor or dynamic initialization of an object with static storage duration is sequenced before that of another, the completion of the destructor of the second is sequenced before the initiation of the destructor of the first.

现在,

Static initialization shall be performed before any dynamic initialization takes place.

显然这回答了第一个问题:由于 p 保证在执行任何动态初始化之前被初始化,因此析构函数在任何动态初始化的对象被销毁后 被调用。

本质上,第二个问题,即几个静态初始化变量的破坏顺序,简化为这些变量的初始化顺序:

Dynamic initialization of a non-local variable with static storage duration is either ordered or unordered. Definitions of explicitly specialized class template static data members have ordered initialization. Other class template static data members (i.e., implicitly or explicitly instantiated specializations) have unordered initialization. Other non-local variables with static storage duration have ordered initialization.

粗体句包括所有不是实例化类的静态数据成员的静态初始化对象。它们在一个翻译单元内排序:

Variables with ordered initialization defined within a single translation unit shall be initialized in the order of their definitions in the translation unit.

总结一下:

  • 属于静态初始化主题且不是实例化类的静态数据成员的变量在翻译文件中以与定义相反的顺序销毁。

  • ...这些变量总是在任何动态初始化的对象被销毁后被销毁。

然而,尽管可能存在争论错误,但 Clang 和 GCC 目前似乎都没有以这种方式实现它:Demo .

关于c++ - 静态初始化的非文字对象的销毁顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27197464/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com