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

2024-12-16


2929. Lifetime of trivially-destructible static or thread-local objects

Section: 6.9.3.4  [basic.start.term]     Status: drafting     Submitter: Mathias Stearn     Date: 2024-08-05

Issue 2256 (adopted in February, 2019) changed the rules such that the lifetimes of objects do not depend on whether the destructor is trivial or not. However, the motivation of that issue mentioned only objects with automatic storage duration. To be able to avoid order-of-destruction issues across translation units, it would be useful to never end the lifetime of trivially-destructible objects with static storage duration and to delay the end of the lifetime of such objects with thread storage duration as long as possible.

Possible resolution [SUPERSEDED]:

  1. Change in 6.9.3.4 [basic.start.term] paragraph 1 as follows:

    Constructed class objects (9.4 [dcl.init]) with static storage duration and having a non-trivial destructor (11.4.7 [class.dtor]) are destroyed and functions registered with std::atexit are called as part of a call to std::exit (17.5 [support.start.term]). The call to std::exit is sequenced before the destructions and the registered functions.
  2. Change in 6.9.3.4 [basic.start.term] paragraph 2 as follows:

    Constructed class objects with thread storage duration within a given thread and having a non-trivial destructor (11.4.7 [class.dtor]) are destroyed as a result of returning from the initial function of that thread and as a result of that thread calling std::exit. The destruction of all those constructed objects with thread storage duration within that thread strongly happens before releasing the storage for objects with thread storage duration within that thread, which in turn strongly happens before destroying any object with static storage duration.

CWG 2024-09-27

Also allow for constant destruction, consider arrays of class type, and adjust the happens-before requirements.

Proposed resolution (approved by CWG 2024-10-11):

  1. Change in 6.9.3.4 [basic.start.term] paragraph 1 as follows:

    Constructed complete objects (9.4 [dcl.init]) with static storage duration and not having constant destruction (7.7 [expr.const]) are destroyed and functions registered with std::atexit are called as part of a call to std::exit (17.5 [support.start.term]). The call to std::exit is sequenced before the destructions and the registered functions.
  2. Change in 6.9.3.4 [basic.start.term] paragraph 2 as follows:

    Constructed complete objects with thread storage duration within a given thread and not having constant destruction (7.7 [expr.const]) are destroyed as a result of returning from the initial function of that thread and as a result of that thread calling std::exit. The destruction of those constructed objects within that thread is sequenced before releasing the storage for all objects with thread storage duration within that thread (6.7.5.3 [basic.stc.thread]). Also, the The destruction of all those constructed objects with thread storage duration within that thread strongly happens before destroying any object with static storage duration.

CWG 2024-11-22

Continue to actually destroy constant-destruction objects, but do so after all dynamic destruction is done.