名稱空間
變體
操作

longjmp

來自 cppreference.com
< c‎ | program
定義於標頭檔案 <setjmp.h>
void longjmp( jmp_buf env, int status );
(C11 之前)
_Noreturn void longjmp( jmp_buf env, int status );
(C11 起)
(直至 C23)
[[noreturn]] void longjmp( jmp_buf env, int status );
(自 C23 起)

載入由之前呼叫 setjmp 儲存的執行上下文 env。此函式不返回。控制轉移到設定 env 的宏 setjmp 的呼叫位置。該 setjmp 隨後返回作為 status 傳遞的值。

如果呼叫 setjmp 的函式已退出(無論是透過返回還是透過堆疊中更高位置的不同 longjmp),則行為未定義。換句話說,只允許在呼叫堆疊中向上進行長跳轉。

跨執行緒跳轉(如果呼叫 setjmp 的函式由另一個執行緒執行)也是未定義行為。

(C11 起)

如果在呼叫 setjmp 時,可變長陣列(VLA) 或另一個 可變修改型別 變數在作用域內,並且控制離開了該作用域,則 longjmp 到該 setjmp 會導致未定義行為,即使控制仍在函式內。

在堆疊向上回溯時,longjmp 不會釋放任何 VLA,如果它們的生命週期以這種方式終止,可能會發生記憶體洩漏

void g(int n)
{
    int a[n]; // a may remain allocated
    h(n); // does not return
}
void h(int n)
{
    int b[n]; // b may remain allocated
    longjmp(buf, 2); // might cause a memory leak for h's b and g's a
}
(C99 起)

目錄

[編輯] 引數

env - 引用由 setjmp 儲存的程式執行狀態的變數
status - setjmp 返回的值。如果它等於 0,則改用 1

[編輯] 返回值

(無)

[編輯] 注意

longjmp 旨在處理函式無法有意義地返回的意外錯誤情況。這類似於其他程式語言中的異常處理。

[編輯] 示例

#include <stdio.h>
#include <setjmp.h>
#include <stdnoreturn.h>
 
jmp_buf my_jump_buffer;
 
noreturn void foo(int status) 
{
    printf("foo(%d) called\n", status);
    longjmp(my_jump_buffer, status + 1); // will return status+1 out of setjmp
}
 
int main(void)
{
    volatile int count = 0; // modified local vars in setjmp scope must be volatile
    if (setjmp(my_jump_buffer) != 5) // compare against constant in an if
        foo(++count);
}

輸出

foo(1) called
foo(2) called
foo(3) called
foo(4) called

[編輯] 參考

  • C17 標準 (ISO/IEC 9899:2018)
  • 7.13.2.1 longjmp 宏 (p: 191-192)
  • C11 標準 (ISO/IEC 9899:2011)
  • 7.13.2.1 longjmp 宏 (p: 263-264)
  • C99 標準 (ISO/IEC 9899:1999)
  • 7.13.2.1 longjmp 宏 (p: 244-245)
  • C89/C90 標準 (ISO/IEC 9899:1990)
  • 4.6.2.1 longjmp 函式

[編輯] 另請參閱

儲存上下文
(函式宏) [編輯]
C++ 文件 for longjmp