17 Language support library [support]

17.5 Startup and termination [support.start.term]

[Note 1: 
The header <cstdlib> declares the functions described in this subclause.
— end note]
[[noreturn]] void _Exit(int status) noexcept;
Effects: This function has the semantics specified in the C standard library.
Remarks: The program is terminated without executing destructors for objects of automatic, thread, or static storage duration and without calling functions passed to atexit() ([basic.start.term]).
The function _Exit is signal-safe.
[[noreturn]] void abort() noexcept;
Effects: This function has the semantics specified in the C standard library.
Remarks: The program is terminated without executing destructors for objects of automatic, thread, or static storage duration and without calling functions passed to atexit() ([basic.start.term]).
The function abort is signal-safe.
int atexit(c-atexit-handler* f) noexcept; int atexit(atexit-handler* f) noexcept;
Effects: The atexit() functions register the function pointed to by f to be called without arguments at normal program termination.
It is unspecified whether a call to atexit() that does not happen before a call to exit() will succeed.
[Note 2: 
The atexit() functions do not introduce a data race ([res.on.data.races]).
— end note]
Implementation limits: The implementation shall support the registration of at least 32 functions.
Returns: The atexit() function returns zero if the registration succeeds, nonzero if it fails.
[[noreturn]] void exit(int status);
Effects:
  • First, objects with thread storage duration and associated with the current thread are destroyed.
    Next, objects with static storage duration are destroyed and functions registered by calling atexit are called.195
    See [basic.start.term] for the order of destructions and calls.
    (Objects with automatic storage duration are not destroyed as a result of calling exit().)196
    If a registered function invoked by exit exits via an exception, the function std​::​terminate is invoked ([except.terminate]).
  • Next, all open C streams (as mediated by the function signatures declared in <cstdio>) with unwritten buffered data are flushed, all open C streams are closed, and all files created by calling tmpfile() are removed.
  • Finally, control is returned to the host environment.
    If status is zero or EXIT_SUCCESS, an implementation-defined form of the status successful termination is returned.
    If status is EXIT_FAILURE, an implementation-defined form of the status unsuccessful termination is returned.
    Otherwise the status returned is implementation-defined.197
int at_quick_exit(c-atexit-handler* f) noexcept; int at_quick_exit(atexit-handler* f) noexcept;
Effects: The at_quick_exit() functions register the function pointed to by f to be called without arguments when quick_exit is called.
It is unspecified whether a call to at_quick_exit() that does not happen before all calls to quick_exit will succeed.
[Note 3: 
The at_quick_exit() functions do not introduce a data race ([res.on.data.races]).
— end note]
[Note 4: 
The order of registration could be indeterminate if at_quick_exit was called from more than one thread.
— end note]
[Note 5: 
The at_quick_exit registrations are distinct from the atexit registrations, and applications might need to call both registration functions with the same argument.
— end note]
Implementation limits: The implementation shall support the registration of at least 32 functions.
Returns: Zero if the registration succeeds, nonzero if it fails.
[[noreturn]] void quick_exit(int status) noexcept;
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.
Objects shall not be destroyed as a result of calling quick_exit.
If a registered function invoked by quick_exit exits via an exception, the function std​::​terminate is invoked ([except.terminate]).
[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.
— end note]
After calling registered functions, quick_exit shall call _Exit(status).
Remarks: The function quick_exit is signal-safe when the functions registered with at_quick_exit are.
See also: ISO/IEC 9899:2018, 7.22.4
195)195)
A function is called for every time it is registered.
196)196)
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.
197)197)
The macros EXIT_FAILURE and EXIT_SUCCESS are defined in <cstdlib>.