[support.start.term]

# 17 Language support library [[support]](./#support)

## 17.5 Startup and termination [support.start.term]

[1](#1)

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

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

The header [<cstdlib>](cstdlib.syn#header:%3ccstdlib%3e "17.2.2 Header <cstdlib> synopsis [cstdlib.syn]") declares the functions described in this subclause[.](#1.sentence-1)

â *end note*]

[ð](#lib:_Exit)

`[[noreturn]] void _Exit(int status) noexcept;
`

[2](#2)

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

*Effects*: This function has the semantics specified in the C standard library[.](#2.sentence-1)

[3](#3)

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

*Remarks*: The program is terminated without executing destructors for objects with automatic,
thread, or static storage duration and without calling functions passed toatexit() ([[basic.start.term]](basic.start.term "6.10.3.4 Termination"))[.](#3.sentence-1)

The function _Exit is [signal-safe](support.signal#def:evaluation,signal-safe "17.14.5 Signal handlers [support.signal]")[.](#3.sentence-2)

[ð](#lib:abort)

`[[noreturn]] void abort() noexcept;
`

[4](#4)

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

*Effects*: This function has the semantics specified in the C standard library[.](#4.sentence-1)

[5](#5)

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

*Remarks*: The program is terminated without executing destructors for objects of
automatic, thread, or static storage
duration and without calling functions passed toatexit() ([[basic.start.term]](basic.start.term "6.10.3.4 Termination"))[.](#5.sentence-1)

The function abort is [signal-safe](support.signal#def:evaluation,signal-safe "17.14.5 Signal handlers [support.signal]")[.](#5.sentence-2)

[ð](#lib:atexit)

`int atexit(c-atexit-handler* f) noexcept;
int atexit(atexit-handler* f) noexcept;
`

[6](#6)

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

*Effects*: Theatexit() functions register the function pointed to by f to be called without arguments at normal program termination[.](#6.sentence-1)

It is unspecified whether a call to atexit() that does not[happen before](intro.multithread#def:happens_before "6.10.2 Multi-threaded executions and data races [intro.multithread]") a call to exit() will succeed[.](#6.sentence-2)

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

The atexit() functions do not introduce a data
race ([[res.on.data.races]](res.on.data.races "16.4.6.10 Data race avoidance"))[.](#6.sentence-3)

â *end note*]

[7](#7)

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

*Implementation limits*: The implementation shall support the registration of at least 32 functions[.](#7.sentence-1)

[8](#8)

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

*Returns*: Theatexit() function returns zero if the registration succeeds,
nonzero if it fails[.](#8.sentence-1)

[ð](#lib:exit)

`[[noreturn]] void exit(int status);
`

[9](#9)

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

*Effects*: 

- [(9.1)](#9.1)

  First, objects with thread storage duration and associated with the current thread
are destroyed[.](#9.1.sentence-1)
  Next, objects with static storage duration are destroyed
and functions registered by callingatexit are called[.](#9.1.sentence-2)[186](#footnote-186 "A function is called for every time it is registered.")
   See [[basic.start.term]](basic.start.term "6.10.3.4 Termination") for the order of destructions and calls[.](#9.1.sentence-3)
  (Objects with automatic storage duration are not destroyed as a result of callingexit()[.](#9.1.sentence-4))[187](#footnote-187 "Objects with automatic storage duration are all destroyed in a program whose main function ([basic.start.main]) contains no objects with automatic storage duration and executes the call to exit(). Control can be transferred directly to such a main function by throwing an exception that is caught in main.")
  If a registered function invoked by exit exits via an exception,
the function std​::​terminate is invoked ([[except.terminate]](except.terminate "14.6.2 The std​::​terminate function"))[.](#9.1.sentence-5)

- [(9.2)](#9.2)

  Next, all open C streams (as mediated by the function
signatures declared in [<cstdio>](cstdio.syn#header:%3ccstdio%3e "31.13.1 Header <cstdio> synopsis [cstdio.syn]"))
with unwritten buffered data are flushed, all open C
streams are closed, and all files created by callingtmpfile() are removed[.](#9.2.sentence-1)

- [(9.3)](#9.3)

  Finally, control is returned to the host environment[.](#9.3.sentence-1)
  If status is zero orEXIT_SUCCESS,
an implementation-defined
form of the status[*successful termination*](#def:successful_termination) is returned[.](#9.3.sentence-2)
  If status isEXIT_FAILURE,
an implementation-defined form of the status[*unsuccessful termination*](#def:unsuccessful_termination) is returned[.](#9.3.sentence-3)
  Otherwise the status returned is implementation-defined[.](#9.3.sentence-4)[188](#footnote-188 "The macros EXIT_­FAILURE and EXIT_­SUCCESS are defined in <cstdlib>.")

[ð](#lib:at_quick_exit)

`int at_quick_exit(c-atexit-handler* f) noexcept;
int at_quick_exit(atexit-handler* f) noexcept;
`

[10](#10)

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

*Effects*: The at_quick_exit() functions register the function pointed to by f to be called without arguments when quick_exit is called[.](#10.sentence-1)

It is unspecified whether a call to at_quick_exit() that does not[happen before](intro.multithread#def:happens_before "6.10.2 Multi-threaded executions and data races [intro.multithread]") all calls to quick_exit will succeed[.](#10.sentence-2)

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

Theat_quick_exit() functions do not introduce a
data race ([[res.on.data.races]](res.on.data.races "16.4.6.10 Data race avoidance"))[.](#10.sentence-3)

â *end note*]

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

The order of registration could be indeterminate if at_quick_exit was called from more
than one thread[.](#10.sentence-4)

â *end note*]

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

Theat_quick_exit registrations are distinct from the atexit registrations,
and applications might need to call both registration functions with the same argument[.](#10.sentence-5)

â *end note*]

[11](#11)

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

*Implementation limits*: The implementation shall support the registration of at least 32 functions[.](#11.sentence-1)

[12](#12)

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

*Returns*: Zero if the registration succeeds, nonzero if it fails[.](#12.sentence-1)

[ð](#lib:quick_exit)

`[[noreturn]] void quick_exit(int status) noexcept;
`

[13](#13)

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

*Effects*: Functions registered by calls to at_quick_exit are called in the
reverse order of their registration, except that a function shall be called after any
previously registered functions that had already been called at the time it was
registered[.](#13.sentence-1)

Objects shall not be destroyed as a result of calling quick_exit[.](#13.sentence-2)

If a registered function invoked by quick_exit exits via an exception,
the function std​::​terminate is invoked ([[except.terminate]](except.terminate "14.6.2 The std​::​terminate function"))[.](#13.sentence-3)

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

A function registered via at_quick_exit is invoked by the thread that calls quick_exit,
which can be a different thread
than the one that registered it, so registered functions cannot rely on the identity
of objects with thread storage duration[.](#13.sentence-4)

â *end note*]

After calling registered functions, quick_exit shall call _Exit(status)[.](#13.sentence-5)

[14](#14)

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

*Remarks*: The function quick_exit is [signal-safe](support.signal#def:evaluation,signal-safe "17.14.5 Signal handlers [support.signal]") when the functions registered with at_quick_exit are[.](#14.sentence-1)

See also: ISO/IEC 9899:2024, 7.24.4

[186)](#footnote-186)[186)](#footnoteref-186)

A function is called for every time it is registered[.](#footnote-186.sentence-1)

[187)](#footnote-187)[187)](#footnoteref-187)

Objects with automatic storage duration are all destroyed in a program whosemain function ([[basic.start.main]](basic.start.main "6.10.3.1 main function"))
contains no objects with automatic storage duration and executes the call toexit()[.](#footnote-187.sentence-1)

Control can be transferred directly to such amain function
by throwing an exception that is caught inmain[.](#footnote-187.sentence-2)

[188)](#footnote-188)[188)](#footnoteref-188)

The macros EXIT_FAILURE and EXIT_SUCCESS are defined in [<cstdlib>](cstdlib.syn#header:%3ccstdlib%3e "17.2.2 Header <cstdlib> synopsis [cstdlib.syn]")[.](#footnote-188.sentence-1)
