命名空间
变体
动作

std::exit

来自 cppreference.com
< cpp‎ | utility‎ | program
 
 
实用程序库
语言支持
类型支持 (基本类型,RTTI)
库功能测试宏 (C++20)
动态内存管理
程序实用程序
协程支持 (C++20)
可变参数函数
调试支持
(C++26)
三向比较
(C++20)
(C++20)(C++20)(C++20)
(C++20)(C++20)(C++20)
通用实用程序
日期和时间
函数对象
格式化库 (C++20)
(C++11)
关系运算符 (C++20 中已弃用)
整数比较函数
(C++20)(C++20)(C++20)   
(C++20)
交换类型操作
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
通用词汇类型
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)
基本字符串转换
(C++17)
(C++17)

 
 
在头文件 <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 析构函数的函数在 obj 构造函数完成时使用 std::atexit 注册一样。
(直到 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