Namespaces
Variants

std:: exit

From cppreference.net
Utilities library
Определено в заголовочном файле <cstdlib>
void exit ( int exit_code ) ;
(до C++11)
[ [ noreturn ] ] void exit ( int exit_code ) ;
(начиная с C++11)

Вызывает нормальное завершение программы.

Выполняется несколько шагов очистки:

1) Объекты со статической продолжительностью хранения уничтожаются, и функции, зарегистрированные вызовом std::atexit , вызываются:
a) Нелокальные объекты со статической продолжительностью хранения уничтожаются в обратном порядке завершения их конструкторов.
b) Функции, зарегистрированные с помощью std::atexit , вызываются в обратном порядке их регистрации, за исключением того, что функция вызывается после любых ранее зарегистрированных функций, которые уже были вызваны на момент её регистрации.
c) Для каждой функции f , зарегистрированной с помощью std::atexit , и каждого нелокального объекта obj со статической продолжительностью хранения,
  • если f зарегистрирована до инициализации obj , f будет вызвана только после уничтожения obj ;
  • если f зарегистрирована после инициализации obj , f будет вызвана только до уничтожения obj .
d) Для каждого локального объекта obj со статической продолжительностью хранения, obj уничтожается так, как если бы функция, вызывающая деструктор obj , была зарегистрирована с помощью std::atexit при завершении конструктора obj .
(до C++11)
1) Деструкторы объектов с поточной продолжительностью хранения , связанных с текущим потоком, деструкторы объектов со статической продолжительностью хранения и функции, зарегистрированные с помощью std::atexit , выполняются параллельно, при этом сохраняются следующие гарантии:
a) Последний деструктор для поточных объектов упорядочен перед первым деструктором для статического объекта.
b) Если завершение конструктора или динамической инициализации для поточного или статического объекта A было упорядочено перед поточным или статическим объектом B, то завершение уничтожения B упорядочено перед началом уничтожения A.
c) Если завершение инициализации статического объекта A было упорядочено перед вызовом std::atexit для некоторой функции F, то вызов F во время завершения упорядочен перед началом уничтожения A.
d) Если вызов std::atexit для некоторой функции F был упорядочен перед завершением инициализации статического объекта A, то начало уничтожения A упорядочено перед вызовом F во время завершения.
e) Если вызов std::atexit для некоторой функции F1 был упорядочен перед вызовом std::atexit для некоторой функции F2, то вызов F2 во время завершения упорядочен перед вызовом F1.
(начиная с C++11)
  • В вышеприведённом,
  • Если любая функция, зарегистрированная с помощью atexit , или любой деструктор статического/поточно-локального объекта выбрасывает исключение, std::terminate вызывается.
  • Если компилятор решил перенести динамическую инициализацию объекта в фазу статической инициализации нелокальной инициализации , порядок разрушения соответствует его предполагаемой динамической инициализации.
  • Если статический объект в области видимости функции (блока) был разрушен, и затем эта функция вызывается из деструктора другого статического объекта, и поток управления проходит через определение этого объекта (или если он используется косвенно, через указатель или ссылку), поведение не определено.
  • Если статический объект в области видимости функции (блока) был инициализирован во время конструирования подобъекта класса или массива, он разрушается только после того, как все подобъекты этого класса или все элементы этого массива были разрушены.
2) Все потоки C сбрасываются и закрываются.
3) Файлы, созданные std::tmpfile , удаляются.
4) Управление возвращается в среду выполнения. Если exit_code равен 0 или EXIT_SUCCESS , возвращается определяемый реализацией статус, указывающий на успешное завершение. Если exit_code равен EXIT_FAILURE , возвращается определяемый реализацией статус, указывающий на неуспешное завершение. В остальных случаях возвращается определяемое реализацией значение статуса.

Стек не раскручивается: деструкторы переменных с автоматической storage duration не вызываются.

Содержание

Связь с функцией main

Возврат из функции main , либо с помощью оператора return , либо при достижении конца функции, выполняет нормальное завершение функции (вызывает деструкторы переменных с автоматической продолжительностью хранения ), а затем выполняет std::exit , передавая аргумент оператора return (или 0 если использовалось неявное возвращение) в качестве exit_code .

Параметры

exit_code - статус завершения программы

Возвращаемое значение

(нет)

Пример

#include <cstdlib>
#include <iostream>
struct Static
{
    ~Static() 
    {
        std::cout << "Static destructor\n";
    }
};
struct Local
{
    ~Local() 
    {
        std::cout << "Local destructor\n";
    }
};
Static static_variable; // Деструктор этого объекта *будет* вызван
void atexit_handler()
{
    std::cout << "atexit handler\n";
}
int main()
{
    Local local_variable; // Деструктор этого объекта *не* будет вызван
    const int result = std::atexit(atexit_handler); // Обработчик будет вызван
    if (result != 0)
    {
        std::cerr << "atexit registration failed\n";
        return EXIT_FAILURE;
    }
    std::cout << "test\n";
    std::exit(EXIT_FAILURE);
    std::cout << "this line will *not* be executed\n";
}

Вывод:

test
atexit handler
Static destructor

Отчеты о дефектах

Следующие отчеты об изменениях поведения, влияющие на дефекты, были применены ретроактивно к ранее опубликованным стандартам C++.

DR Применяется к Поведение в опубликованной версии Корректное поведение
LWG 3 C++98 во время очистки поведение было неясным, когда (1) функция
регистрируется с помощью std::atexit или (2) инициализируется
статический локальный объект
прояснено

Смотрите также

вызывает аварийное завершение программы (без очистки)
(функция)
регистрирует функцию для вызова при std::exit() вызове
(функция)
(C++11)
вызывает быстрое завершение программы без полной очистки
(функция)
регистрирует функцию для вызова при std::quick_exit вызове
(функция)