简体   繁体   English

从全局对象的构造函数调用时的std :: atexit排序

[英]std::atexit ordering when called from a global object's constructor

cppreference says about std::atexit : cppreference说关于std::atexit

The functions may be called concurrently with the destruction of the objects with static storage duration and with each other, maintaining the guarantee that if registration of A was sequenced-before the registration of B, then the call to B is sequenced-before the call to A, same applies to the sequencing between static object constructors and calls to atexit 这些函数可以与具有静态存储持续时间的对象的销毁同时被调用,并且保持如果在B的注册之前如果A的注册被排序,则在调用之前对B的调用进行排序的保证。 A,同样适用于静态对象构造函数和对atexit的调用之间的顺序

I understand that passage to mean that, if std::atexit is called during static initialization, the registered function will be called during the destruction of static objects just before the destruction of the static object which was last initialized when the std::atexit that registered the function was called. 我理解这段话意味着,如果在静态初始化期间调用std::atexit ,则在破坏静态对象时会调用注册函数,而静态对象是在std::atexit时最后初始化的静态对象。注册函数被调用。 I also interpret "may be called concurrently" to mean the calls can occur between static object destructions as opposed to the multi-threaded interpretation of the word. 我还解释“可以同时调用”意味着调用可以发生在静态对象析构之间,而不是对单词的多线程解释。

What I'm wondering is whether a object is considered as initialized (in the context of this ordering) when it's initialization begins or when it completes. 我想知道的是,当初始化开始或完成时,对象是否被视为已初始化(在此排序的上下文中)。 I wrote a short test to test this : 我写了一个简短的测试来测试这个:

#include <cstdlib>
#include <iostream>

struct foo
{
    foo() 
    {
        std::cout << "ctor\n";
        std::atexit([]() { std::cout << "atexit\n"; });
    }
    ~foo()
    {
        std::cout << "dtor\n";
    }
};

foo my_foo;

int main()
{
    return 0;
}

The output I get is ( http://cpp.sh/3bllu ) : 我得到的输出是( http://cpp.sh/3bllu ):

ctor
dtor
atexit

This leads me to believe that my_foo is not considered to be initialized in this context until it's construction finishes. 这使我相信在构造完成之前, my_foo不会被认为是在此上下文中初始化的。 In other words, the function is considered to have been registered before my_foo was initialized so the registered function executes after my_foo 's destruction. 换句话说,该功能被认为之前已经注册my_foo被初始化,所以注册的函数后,执行my_foo的破坏。

I can't seem to find anything that would guarantee this behavior and I'm not even entirely sure my initial interpretation of the cited passage is correct. 我似乎找不到任何可以保证这种行为的东西,我甚至不完全确定我对引用段落的初步解释是正确的。 Is the behavior I've described something that I can rely on or is it implementation defined or even undefined behavior? 我描述的行为是我可以依赖的,还是实现定义甚至未定义的行为?

The call to the destructor will happen before the call to the function passed to atexit . 对函数的调用将在调用传递给atexit的函数之前发生。 From [basic.start.term], p5: 从[basic.start.term],p5:

If a call to std::atexit strongly happens before the completion of the initialization of an object with static storage duration, the call to the destructor for the object is sequenced before the call to the function passed to std::atexit . 如果在具有静态存储持续时间的对象初始化完成之前强烈发生对std::atexit的调用,则在调用传递给std::atexit的函数之前,对对象的析构函数的调用将被排序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM