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

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

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

我理解这段话的意思是,如果 std::atexit 在静态初始化期间被调用,注册的函数将在静态对象的销毁期间被调用,就在最后一次初始化的静态对象的销毁之前调用了注册函数的std::atexit。我还解释 "may be called concurrently" 意味着调用可以发生在静态对象破坏之间,而不是单词的多线程解释。

我想知道的是,一个对象在初始化开始或完成时是否被视为已初始化(在此排序的上下文中)。我写了一个简短的测试来测试这个:

#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;
}

我得到的输出是 (http://cpp.sh/3bllu) :

ctor
dtor
atexit

这让我相信 my_foo 在构造完成之前不会被视为在此上下文中初始化。换句话说,该函数被认为在 my_foo 初始化之前已经注册,因此注册函数在 my_foo 销毁后执行。

我似乎找不到任何可以保证这种行为的东西,我什至不能完全确定我对引用段落的初步解释是否正确。我所描述的行为是我可以依赖的,还是实现定义的,甚至是未定义的行为?

对析构函数的调用将在对传递给 atexit 的函数的调用之前发生。来自 [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.