This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 113d. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-03-20


946. Order of destruction of local static objects and calls to std::atexit

Section: 6.9.3.3  [basic.start.dynamic]     Status: CD2     Submitter: Fraser Ross     Date: 28 July, 2009

[Voted into WP at March, 2010 meeting.]

17.5 [support.start.term] paragraph 7 says that the order of destruction of objects with static storage duration and calls to functions registered by calling std::atexit is given in 6.9.3.3 [basic.start.dynamic]. Paragraph 1 of 6.9.3.3 [basic.start.dynamic] says,

If the completion of the constructor or dynamic initialization of an object with static storage duration is sequenced before that of another, the completion of the destructor of the second is sequenced before the initiation of the destructor of the first.

This wording covers both local and namespace-scope objects, so it fixes the relative ordering of local object destructors with respect to those of namespace scope. Paragraph 3 says,

If the completion of the initialization of a non-local object with static storage duration is sequenced before a call to std::atexit (see <cstdlib>, 17.5 [support.start.term]), the call to the function passed to std::atexit is sequenced before the call to the destructor for the object. If a call to std::atexit is sequenced before the completion of the initialization of a non-local 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.

This fixes the relative ordering of destructors for namespace scope objects with respect to calls of atexit functions. However, the relative ordering of local destructors and atexit functions is left unspecified.

In the 2003 Standard, this was clear: 18.3 paragraph 8 said,

A local static object obj3 is destroyed at the same time it would be if a function calling the obj3 destructor were registered with atexit at the completion of the obj3 constructor.

Proposed resolution (October, 2009):

Change 6.9.3.3 [basic.start.dynamic] paragraph 3 as follows:

If the completion of the initialization of a non-local an object with static storage duration is sequenced before a call to std::atexit (see <cstdlib>, 17.5 [support.start.term]), the call to the function passed to std::atexit is sequenced before the call to the destructor for the object. If a call to std::atexit is sequenced before the completion of the initialization of a non-local 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...