std::exit
来自 cppreference.com
在头文件 <cstdlib> 中定义 |
||
void exit( int exit_code ); |
(直到 C++11) | |
[[noreturn]] void exit( int exit_code ); |
(自 C++11 起) | |
导致正常程序终止发生。
执行若干清理步骤
1) 销毁具有静态存储期的对象,并调用通过调用 std::atexit 注册的函数
a) 具有静态存储期的非局部对象以其构造函数完成的相反顺序被销毁。
b) 使用 std::atexit 注册的函数以其注册的相反顺序被调用,但如果一个函数是在其注册时已经被调用的先前注册函数之后被调用,则该函数将在这些先前注册函数之后被调用。
c) 对于使用 std::atexit 注册的每个函数 f 和每个具有静态存储期的非局部对象 obj,
|
(直到 C++11) |
a) 线程局部对象的最后一个析构函数 按顺序先于 静态对象的第一个析构函数。
b) 如果线程局部或静态对象 A 的构造函数或 动态初始化 的完成按顺序先于线程局部或静态对象 B,则 B 的销毁完成按顺序先于 A 的销毁开始。
c) 如果静态对象 A 的初始化完成按顺序先于对某个函数 F 的 std::atexit 的调用,则终止期间对 F 的调用按顺序先于 A 的销毁开始。
d) 如果对某个函数 F 的 std::atexit 的调用按顺序先于静态对象 A 的初始化完成,则 A 的销毁开始按顺序先于终止期间对 F 的调用。
|
(自 C++11 起) |
- 在以上内容中,
- 如果使用
atexit
注册的任何函数或任何静态/线程局部对象的析构函数抛出异常,则会调用 std::terminate。 - 如果编译器选择将对象的动态初始化提升到 非局部初始化 的静态初始化阶段,则销毁的顺序将遵循其原本的动态初始化。
- 如果一个函数局部(块作用域)静态对象被销毁,然后从另一个静态对象的析构函数调用该函数,并且控制流经过该对象的定义(或如果它通过指针或引用间接使用),则行为未定义。
- 如果在类或数组的子对象构造期间初始化了一个函数局部(块作用域)静态对象,则它仅在该类的所有子对象或该数组的所有元素都被销毁后才被销毁。
- 如果使用
2) 刷新和关闭所有 C 流。
3) 删除由 std::tmpfile 创建的文件。
4) 控制权返回给宿主环境。如果
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
|