Order between destruction of global object and atexit in C++
Asked Answered
S

1

25

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().

Scholastic answered 15/4, 2013 at 7:43 Comment(5)
I suspect that order isn't 100% sure to be defined. Why do you care?Ashil
Create another global object before MyClass and call atexit( onExit ) in its constructor to check.Olympian
Want to control lifetime of objects, use dynamic ones.Tempura
Actually, I have a singleton memory manager object is destructed by atexit and global object is using member variable managed by that memory manager. So global object is destructed before memorymanager destruction by atexit.Scholastic
@zelon: [off-topic] As an irrelevant note, using static keyword on a file-scope (global scope) variable probably does not do what you think it does. That is, the static in your example code is redundant.Definition
E
20

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.

Effervesce answered 15/4, 2013 at 7:49 Comment(3)
Whether g++ is compliant or not depends on the compiler options and the platform. (It's compliant when it can be, but since on many platforms, the atexit function is supplied by the platform, it's not always reasonably possible.)Yulan
sorry. I wrote a mistake. onexit() is invoked before ~MyClass. I was so confused while tidying example code.Scholastic
@zelon: OK. Then the behavior is correct and this is what the C++ Standard specifies.Effervesce

© 2022 - 2024 — McMap. All rights reserved.