std::exit
| Определено в заголовке <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 со статической длительностью хранения,
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. - Если компилятор решил перенести динамическую инициализацию объекта на этап статической инициализации нелокальной инициализации, порядок уничтожения учитывает его предполагаемую динамическую инициализацию.
- Если статический объект, локальный для функции (с областью видимости блока), был уничтожен, и затем эта функция вызывается из деструктора другого статического объекта, и поток управления проходит через определение этого объекта (или если он используется косвенно, через указатель или ссылку), поведение не определено.
- Если статический объект, локальный для функции (с областью видимости блока), был инициализирован во время создания подобъекта класса или элемента массива, он уничтожается только после уничтожения всех подобъектов этого класса или всех элементов этого массива.
- Если любая функция, зарегистрированная с помощью
exit_code равно 0 или EXIT_SUCCESS, возвращается определяемый реализацией статус, указывающий на успешное завершение. Если exit_code равно EXIT_FAILURE, возвращается определяемый реализацией статус, указывающий на неуспешное завершение. В остальных случаях возвращается определяемое реализацией значение статуса.Стек не разворачивается: деструкторы переменных с автоматической длительностью хранения не вызываются.
Связь с функцией 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)
|
вызывает быстрое завершение программы без полной очистки
(функция) |
|
(C++11)
|
регистрирует функцию для вызова при
std::quick_exit
вызове
(функция) |
|
Документация C
для
exit
|
|