c++atexitorder-of-executionglobal-object

Order between destruction of global object and atexit in C++


I wonder that can sure order between destruction of global object and atexit in C++

I have a global object and register atexit function like below:

static MyClass g_class;

void onExit()
{
    // do some destruction
}

int main()
{
    atexit(onExit);

    return 0;
}

I've found onExit() is invoked before MyClass::~MyClass() in Visual Studio 2012 and gcc4.7.2. Am I sure that onExit is always invoked before global object(like g_class) destruction?

I wonder global object register order and atexit register order use same order table. Or there is no relation between global object order and atexit order?

Edited : Sorry I wrote a mistake. I'm so confused while tidying example code. onExit() is invoked before ~MyClass().


Solution

  • UPDATE: The OP made some confusion, and it seems VC11 does indeed behave as specified by the C++11 Standard. The following answer was written in the assumption that it did not.

    Therefore, the answer to this question:

    Am I sure that onExit is always invoked before global object(like g_class) destruction?

    Is "Yes", as long as you are working with a fully-compliant compiler.


    I've found MyClass::~MyClass() is invoked before onExit() in Visual Studio 2012.

    If this is the case, then it is a bug in VC11. Per Paragraph 3.6.3/1 of the C++11 Standard:

    Destructors (12.4) for initialized objects (that is, objects whose lifetime (3.8) has begun) with static storage duration are called as a result of returning from main and as a result of calling std::exit (18.5). [...]

    Also, per Paragraph 3.6.3/3:

    If the completion of the initialization of an object with static storage duration is sequenced before a call to std::atexit (see <cstdlib>, 18.5), the call to the function passed to std::atexit is sequenced before the call to the destructor for the object.

    Therefore, in your case, onexit() should be invoked before the destructor of MyClass.

    As far as I can tell, Clang 3.2 and GCC 4.8.0 are compliant in this respect, as shown in this live example.