c – 静态初始化的非文字对象的破坏顺序

前端之家收集整理的这篇文章主要介绍了c – 静态初始化的非文字对象的破坏顺序前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
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&C++相关文章