std::exit (3) - Linux Manuals

std::exit: std::exit

NAME

std::exit - std::exit

Synopsis


Defined in header <cstdlib>
void exit( int exit_code ); (until C++11)
[[noreturn]] void exit( int exit_code ); (since C++11)


Causes normal program termination to occur.
Several cleanup steps are performed:


1) destructors of objects with static storage duration are called in reverse order of completion of their constructors or the completion of their dynamic_initialization, and the functions passed to std::atexit are called in reverse order they are registered (last one first).
a) any static objects whose initialization was completed before the call to std::atexit for some function F will be destroyed after the call to F during program termination. (until C++11)
b) any static objects whose construction began after the call to std::atexit for some function F will be destroyed before the call to F during program termination (this includes the case where std::atexit was called from the constructor of the static object)
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 (since C++11)
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


      * 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
3) files created by std::tmpfile are removed
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

Return value


(none)

Example


// Run this code


  #include <iostream>
  #include <cstdlib>


  class Static {
  public:


      ~Static()
      {
          std::cout << "Static dtor\n";
      }
  };


  class Local {
  public:
      ~Local()
      {
          std::cout << "Local dtor\n";
      }
  };


  Static static_variable; // dtor of this object *will* be called


  void atexit_handler()
  {
      std::cout << "atexit handler\n";
  }


  int main()
  {
      Local local_variable; // dtor of this object will *not* be called
      const int result = std::atexit(atexit_handler); // handler will be called


      if (result != 0) {
          std::cerr << "atexit registration failed\n";
          return EXIT_FAILURE;
      }


      std::cout << "test\n";
      std::exit(EXIT_FAILURE);
  }

Output:


  test
  atexit handler
  Static dtor

See also


              causes abnormal program termination (without cleaning up)
abort (function)
              registers a function to be called on std::exit() invocation
atexit (function)


quick_exit causes quick program termination without completely cleaning up
              (function)
(C++11)


at_quick_exit registers a function to be called on quick_exit invocation
              (function)
(C++11)