24

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

Joshua
  • 40,822
  • 8
  • 72
  • 132
zelon
  • 297
  • 2
  • 8
  • I suspect that order isn't 100% sure to be defined. Why do you care? – Mats Petersson Apr 15 '13 at 07:44
  • Create another global object before `MyClass` and call `atexit( onExit )` in its constructor to check. – lapk Apr 15 '13 at 07:50
  • 1
    Want to control lifetime of objects, use dynamic ones. – PiotrNycz Apr 15 '13 at 07:53
  • 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. – zelon Apr 15 '13 at 08:33
  • @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. – yzt Apr 15 '13 at 20:14

1 Answers1

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.

Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
  • 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.) – James Kanze Apr 15 '13 at 07:53
  • sorry. I wrote a mistake. onexit() is invoked before ~MyClass. I was so confused while tidying example code. – zelon Apr 15 '13 at 08:46
  • 2
    @zelon: OK. Then the behavior is correct and this is what the C++ Standard specifies. – Andy Prowl Apr 15 '13 at 08:47