名稱空間
變體
操作

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
  • 如果 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 函式的關係

主函式返回,無論是透過 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++ 標準。

缺陷報告 應用於 釋出時的行為 正確的行為
LWG 3 C++98 在清理期間,當 (1) 函式透過
std::atexit 註冊或 (2) 靜態區域性物件初始化時,行為不明確。
已明確

[編輯] 參閱

導致程式異常終止(不進行清理)
(函式) [編輯]
註冊一個在呼叫 std::exit() 時被呼叫的函式
(函式) [編輯]
導致程式快速終止而不完全清理
(函式) [編輯]
註冊一個函式,在呼叫 std::quick_exit 時被呼叫
(函式) [編輯]
C 文件 關於 exit