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 со статической длительностью хранения:
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. - Если компилятор перенёс динамическую инициализацию объекта в фазу статической инициализации при нелокальной инициализации, порядок разрушения соответствует тому, который был бы при динамической инициализации.
- Если локальный для функции (с блочной областью видимости) статический объект был разрушен, а затем эта функция вызывается из деструктора другого статического объекта и поток управления проходит через определение этого объекта (или если он используется косвенно, через указатель или ссылку), поведение не определено.
- Если локальный для функции (с блочной областью видимости) статический объект был инициализирован во время конструирования подобъекта класса или элемента массива, он разрушается только после разрушения всех подобъектов этого класса или всех элементов этого массива.
std::tmpfile, удаляются.exit_code — это 0 или EXIT_SUCCESS, возвращается определённое реализацией значение, указывающее на успешное завершение. Если exit_code — это EXIT_FAILURE, возвращается определённое реализацией значение, указывающее на неуспешное завершение. В остальных случаях возвращается определённое реализацией значение статуса.Стек не раскручивается: деструкторы переменных с автоматической длительностью хранения не вызываются.
Связь с главной функцией
Возврат из главной функции с помощью оператора 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; // Destructor of this object *will* be called
void atexit_handler()
{
std::cout << "atexit handler\n";
}
int main()
{
Local local_variable; // Destructor 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);
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 |
|
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/utility/program/exit