[basic.start.term]

# 6 Basics [[basic]](./#basic)

## 6.10 Program execution [[basic.exec]](basic.exec#basic.start.term)

### 6.10.3 Start and termination [[basic.start]](basic.start#term)

#### 6.10.3.4 Termination [basic.start.term]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7470)

Constructed objects ([[dcl.init]](dcl.init "9.5 Initializers"))
with static storage duration are destroyed
and functions registered with std​::​atexit are called as part of a call tostd​::​exit ([[support.start.term]](support.start.term "17.5 Startup and termination"))[.](#1.sentence-1)

The call to std​::​exit is sequenced before
the destructions and the registered functions[.](#1.sentence-2)

[*Note [1](#note-1)*:

Returning from main invokes std​::​exit ([[basic.start.main]](basic.start.main "6.10.3.1 main function"))[.](#1.sentence-3)

â *end note*]

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7487)

Constructed objects with thread storage duration within a given thread
are destroyed as a result of returning from the initial function of that thread and as a
result of that thread calling std​::​exit[.](#2.sentence-1)

The destruction of all constructed objects with thread storage
duration within that thread strongly happens before destroying
any object with static storage duration[.](#2.sentence-2)

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7495)

If the completion of the constructor or dynamic initialization of an object with static
storage duration strongly happens before that of another, the completion of the destructor
of the second is sequenced before the initiation of the destructor of the first[.](#3.sentence-1)

If the completion of the constructor or dynamic initialization of an object with thread
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[.](#3.sentence-2)

If an object is
initialized statically, the object is destroyed in the same order as if
the object was dynamically initialized[.](#3.sentence-3)

For an object of array or class
type, all subobjects of that object are destroyed before any block
variable with static storage duration initialized during the construction
of the subobjects is destroyed[.](#3.sentence-4)

If the destruction of an object with static or thread storage duration
exits via an exception,
the function std​::​terminate is called ([[except.terminate]](except.terminate "14.6.2 The std​::​terminate function"))[.](#3.sentence-5)

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7512)

If a function contains a block variable of static or thread storage duration that has been
destroyed and the function is called during the destruction of an object with static or
thread storage duration, the program has undefined behavior if the flow of control
passes through the definition of the previously destroyed block variable[.](#4.sentence-1)

[*Note [2](#note-2)*:

Likewise, the behavior is undefined
if the block variable is used indirectly (e.g., through a pointer)
after its destruction[.](#4.sentence-2)

â *end note*]

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7523)

If the completion of the initialization of an object with static storage
duration strongly happens before a call to std​::​atexit (see[<cstdlib>](cstdlib.syn#header:%3ccstdlib%3e "17.2.2 Header <cstdlib> synopsis [cstdlib.syn]"), [[support.start.term]](support.start.term "17.5 Startup and termination")), the call to the function passed tostd​::​atexit is sequenced before the call to the destructor for the object[.](#5.sentence-1)

If a
call to std​::​atexit strongly happens before the completion of the initialization of
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[.](#5.sentence-2)

If a
call to std​::​atexit strongly happens before another call to std​::​atexit, the
call to the function passed to the second std​::​atexit call is sequenced before
the call to the function passed to the first std​::​atexit call[.](#5.sentence-3)

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7537)

If there is a use of a standard library object or function not permitted within signal
handlers ([[support.runtime]](support.runtime "17.14 Other runtime support")) that does not happen before ([[intro.multithread]](intro.multithread "6.10.2 Multi-threaded executions and data races"))
completion of destruction of objects with static storage duration and execution ofstd​::​atexit registered functions ([[support.start.term]](support.start.term "17.5 Startup and termination")), the program has
undefined behavior[.](#6.sentence-1)

[*Note [3](#note-3)*:

If there is a use of an object with static storage
duration that does not happen before the object's destruction, the program has undefined
behavior[.](#6.sentence-2)

Terminating every thread before a call to std​::​exit or the exit frommain is sufficient, but not necessary, to satisfy these requirements[.](#6.sentence-3)

These
requirements permit thread managers as static-storage-duration objects[.](#6.sentence-4)

â *end note*]

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7551)

Calling the function std​::​abort() declared in[<cstdlib>](cstdlib.syn#header:%3ccstdlib%3e "17.2.2 Header <cstdlib> synopsis [cstdlib.syn]") terminates the program without executing any destructors
and without calling
the functions passed to std​::​atexit() or std​::​at_quick_exit()[.](#7.sentence-1)
