std::exit - cppreference.com

From cppreference.com

Defined in header

<cstdlib>

voidexit(intexit_code);(until C++11)[[noreturn]]voidexit(intexit_code);(since C++11)Causes normal program termination to occur.

Several cleanup steps are performed:

1) Objects with static storage duration are destroyed and functions registered by calling

std::atexit

are called:

a) Non-local objects with static storage duration are destroyed in the reverse order of the completion of their constructor.

b) Functions registered with

std::atexit

are called in the reverse order of their registration, except that a function is called after any previously registered functions that had already been called at the time it was registered.

c) For each function f registered with

std::atexit

and each non-local object obj of static storage duration,

if f is registered before the initialization of obj, f will only be called after the destruction of obj;

if f is registered after the initialization of obj, f will only be called before the destruction of obj.

d) For each local object obj with static storage duration, obj is destroyed as if a function calling the destructor of obj were registered with

std::atexit

at the completion of the constructor of obj.

(until C++11)1) The destructors of objects with thread local

storage duration

that are associated with the current thread, the destructors of objects with static storage duration, and the functions registered with

std::atexit

are executed concurrently, while maintaining the following guarantees:

a) The last destructor for thread-local objects is

sequenced-before

the first destructor for a static object.

b) If the completion of the constructor or

dynamic initialization

for thread-local or static object A was sequenced-before thread-local or static object B, the completion of the destruction of B is sequenced-before the start of the destruction of A.

c) If the completion of the initialization of a static object A was sequenced-before the call to

std::atexit

for some function F, the call to F during termination is sequenced-before the start of the destruction of A.

d) If the call to

std::atexit

for some function F was sequenced-before the completion of initialization of a static object A, the start of the destruction of A is sequenced-before the call to F during termination.

e) If a call to

std::atexit

for some function F1 was sequenced-before the call to

std::atexit

for some function F2, then the call to F2 during termination is sequenced-before the call to F1.

(since C++11)In the above,

If any function registered with atexit or any destructor of static/thread-local object throws an exception,

std::terminate

is called.

If the compiler opted to lift dynamic initialization of an object to the static initialization phase of

non-local initialization

, the sequencing of destruction honors its would-be dynamic initialization.

If a function-local (block-scope) static object was destroyed and then that function is called from the destructor of another static object and the control flow passes through the definition of that object (or if it is used indirectly, via pointer or reference), the behavior is undefined.

If a function-local (block-scope) static object was initialized during construction of a subobject of a class or array, it is only destroyed after all subobjects of that class or all elements of that array were destroyed.

2) All C streams are flushed and closed.

4) Control is returned to the host environment. If exit_code is 0 or

EXIT_SUCCESS

, an implementation-defined status indicating successful termination is returned. If exit_code is

EXIT_FAILURE

, an implementation-defined status indicating unsuccessful termination is returned. In other cases implementation-defined status value is returned.

Stack is not unwound: destructors of variables with automatic

storage duration

are not called.

Relationship with the main function

Returning from the

main function

, either by a return statement or by reaching the end of the function performs the normal function termination (calls the destructors of the variables with automatic

storage durations

) and then executes std::exit, passing the argument of the return statement (or 0 if implicit return was used) as exit_code.

Parameters

exit_code - exit status of the program Example

Run this code

#include<cstdlib>#include<iostream>structStatic{~Static(){std::cout<<"Static destructor\n";}};structLocal{~Local(){std::cout<<"Local destructor\n";}};Staticstatic_variable;// Destructor of this object *will* be calledvoidatexit_handler(){std::cout<<"atexit handler\n";}intmain(){Locallocal_variable;// Destructor of this object will *not* be calledconstintresult=std::atexit(atexit_handler);// Handler will be calledif(result!=0){std::cerr<<"atexit registration failed\n";returnEXIT_FAILURE;}std::cout<<"test\n";std::exit(EXIT_FAILURE);std::cout<<"this line will *not* be executed\n";}Output:

test atexit handler Static destructor Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior

LWG 3

C++98 during cleanup, the behavior was unclear when (1) a function is
registered with

std::atexit

or (2) a static local object is initialized made clear See also