命名空间
变体
操作

std::exit

来自 cppreference.cn
< cpp‎ | utility‎ | program
 
 
 
 
定义于头文件 <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
  • fobj 初始化前注册,则 f 将仅在 obj 销毁后被调用;
  • fobj 初始化后注册,则 f 将仅在 obj 销毁前被调用。
d) 对于每个局部静态存储期对象 objobj 被销毁,如同在 obj 的构造函数完成后,以 std::atexit 注册了调用 obj 的析构函数的函数。
(直到 C++11)
1) 与当前线程关联的线程局部存储期对象的析构函数、静态存储期对象的析构函数,和用 std::atexit 注册的函数并发执行,同时保持下列保证:
a) 线程局部对象的最后析构函数先序于静态对象的首个析构函数。
b) 若线程局部或静态对象 A 的构造函数完成或动态初始化先序于线程局部或静态对象 B,则 B 的析构完成先序于 A 的析构开始。
c) 若静态对象 A 的初始化完成先序于对某函数 F 的 std::atexit 调用,则终止期间对 F 的调用先序于 A 的析构开始。
d) 若对某函数 F 的 std::atexit 调用先序于静态对象 A 的初始化完成,则 A 的析构开始先序于终止期间对 F 的调用。
e) 若对某函数 F1 的 std::atexit 调用先序于对某函数 F2 的 std::atexit 调用,则终止期间对 F2 的调用先序于对 F1 的调用。
(自 C++11 起)
  • 在以上中,
  • 若任何用 atexit 注册的函数或任何静态/线程局部对象的析构函数抛出异常,则调用 std::terminate
  • 若编译器选择提升对象的动态初始化到非局部初始化的静态初始化阶段,则销毁的顺序会尊重其本应的动态初始化顺序。
  • 若函数局部(块作用域)静态对象被销毁,之后从另一静态对象的析构函数调用该函数,且控制流通过该对象的定义(或若通过指针或引用间接使用),则行为未定义。
  • 若函数局部(块作用域)静态对象在类或数组的子对象的构造期间初始化,则它仅在该类所有子对象或该数组所有元素均被销毁后销毁。
2) 所有 C 流均被刷新并关闭。
3)std::tmpfile 创建的文件被移除。
4) 控制权返回到宿主环境。若 exit_code0EXIT_SUCCESS,则返回实现定义的指示成功终止的状态。若 exit_codeEXIT_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() 调用时调用的函数
(函数) [编辑]
导致快速程序终止,不完全清理
(函数) [编辑]
注册要在 std::quick_exit 调用时调用的函数
(函数) [编辑]
C 文档 关于 exit