std:: exit
From cppreference.net
|
定义于头文件
<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 函数
返回时,无论是通过
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++标准。
| 缺陷报告 | 适用范围 | 发布时行为 | 正确行为 |
|---|---|---|---|
| LWG 3 | C++98 | 在清理过程中,当(1)函数通过 std::atexit 注册或(2)静态局部对象被初始化时,行为不明确 | 已明确说明 |
参见
|
导致程序异常终止(不进行清理操作)
(函数) |
|
|
注册在调用
std::exit()
时执行的函数
(函数) |
|
|
(C++11)
|
导致程序快速终止而不完全清理
(函数) |
|
(C++11)
|
注册在调用
std::quick_exit
时执行的函数
(函数) |
|
C 文档
for
exit
|
|