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) Если завершение конструктора или динамической инициализации для объекта с локальной длительностью хранения или статического объекта А было предшествующим объекту с локальной длительностью хранения или статического объекта 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, возвращается определённый реализацией статус, указывающий на неудачное завершение. В других случаях возвращается значение статуса, определённое реализацией.Стек не разворачивается: деструкторы переменных с автоматической длительностью хранения не вызываются.
Связь с функцией 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; // 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/w/cpp/utility/program/exit