setjmp和longjmp函式使用詳解

2021-07-01 19:05:25 字數 1649 閱讀 7466

非區域性跳轉語句---setjmp和longjmp函式。非區域性指的是,這不是由普通c語言goto,語句在乙個函式內實施的跳轉,而是在棧上跳過若干呼叫幀,返回到當前函式呼叫路徑上的某乙個函式中。

#include

int setjmp(jmp_buf  env);

返回值:若直接呼叫則返回0,若從longjmp呼叫返回則返回非0值

void longjmp(jmp_buf env,int val);

在希望返回到的位置呼叫setjmp,此位置在main函式中,因為直接呼叫該函式,所以其返回值為0.setjmp引數evn的型別是乙個特殊的型別jmp_buf,這一資料型別是某種形式的陣列,其中存放在呼叫longjmp時能用來恢復棧狀態的所有資訊。因為需要在另乙個函式中引用env變數,所以規範的處理方式是將env變數定義為全域性變數。

當檢查到乙個錯誤時,則以兩個引數呼叫longjmp函式,第乙個就是在呼叫setjmp時所用的env,第二個引數是具有非0值的val,它將成為從setjmp處返回的值。使用第二個引數的原因是對於乙個setjmp可以有多個longjmp。

下面我們可以看乙個簡單的例子:

#include 

#include 

#include 

#include 

void fun1(void);

void fun2(void);

jmp_buf jmpbuffer;

void main(void)

else

exit(0);

}return 1;

} void fun1(void)

void fun2(void)

這個函式的執行結果是:

root@root:~/program/test_program$ ./jmp_test

first run

in fun1

在使用longjmp跳轉到setjmp中時,程式主動的退出了!相當於丟擲乙個異常退出!其實這兩個函式可以模擬c++中的異常函式:

使用setjmp和longjmp要注意以下幾點:

1、setjmp與longjmp結合使用時,它們必須有嚴格的先後執行順序,也即先呼叫setjmp函式,之後再呼叫longjmp函式,以恢復到先前被儲存的「程式執行點」。否則,如果在setjmp呼叫之前,執行longjmp函式,將導致程式的執行流變的不可**,很容易導致程式崩潰而退出

2、不要假設暫存器型別的變數將總會保持不變。在呼叫longjmp之後,通過setjmp所返回的控制流中,程式中暫存器型別的變數將不會被恢復。暫存器型別的變數,是指為了提高程式的執行效率,變數不被儲存在記憶體中,而是直接被儲存在暫存器中。暫存器型別的變數一般都是臨時變數,在c語言中,通過register定義,或直接嵌入彙編**的程式。這種型別的變數。

longjmp必須在setjmp呼叫之後,而且longjmp必須在setjmp的作用域之內。具體來說,在乙個函式中使用setjmp來初始化乙個全域性標號,然後只要該函式未曾返回,那麼在其它任何地方都可以通過longjmp呼叫來跳轉到 setjmp的下一條語句執行。實際上setjmp函式將發生呼叫處的區域性環境儲存在了乙個jmp_buf的結構當中,只要主調函式中對應的記憶體未曾釋放 (函式返回時區域性記憶體就失效了),那麼在呼叫longjmp的時候就可以根據已儲存的jmp_buf引數恢復到setjmp的地方執行。

C語言中的setjmp和longjmp函式

c語言的setjmp 異常處理與構建協作式多工系統 int setjmp jmp buf envbuf 巨集函式setjmp 在緩衝區envbuf中儲存系統堆疊裡的內容,供longjmp 以後使用,setjmp 必須使用標頭檔案setjmp.h。呼叫setjmp 巨集時,返回值為0,然而longjm...

setjmp函式和longjmp函式

這兩個函式是為了解決深層次函式巢狀返回的問題。函式原型 include int setjmp jmp buf env 返回值 若直接呼叫則返回0,若從longjmp呼叫返回則返回非0值。void longjmp jmp buf env,int val 在希望返回的位置呼叫setjmp,引數env通常...

setjmp和longjmp的用法

在c中,goto語句是不能跨越函式的,而執行這類跳轉功能的就是函式setjmp和longjmp,這兩個函式對於處理發生在深層巢狀函式呼叫中的出錯情況是非常有用的 include int setjmp jmp buf env setjmp 函式是一次呼叫,2次返回,第一次呼叫時返回0,而在第二次返回時...