-
setjmp
鎖定
setjmp屬於C函數庫,作用是分別承擔非局部標號和goto作用。
- 中文名
- setjmp
- 類 型
- 計算機語句
- 隸 屬
- C函數庫
- 作 用
- 分別承擔非局部標號和goto作用
與刺激的abort()和exit()相比,goto語句看起來是處理異常的更可行方案。不幸的是,goto是本地的:它只能跳到所在函數內部的標號上,而不能將控制權轉移到所在程序的任意地點(當然,除非你的所有代碼都在main體中)。
為了解決這個限制,C函數庫提供了setjmp()和longjmp()函數,它們分別承擔非局部標號和goto作用。頭文件<setjmp.h>申明瞭這些函數及同時所需的jmp_buf數據類型。
原理非常簡單:
1.setjmp(j)設置“jump”點,用正確的程序上下文填充jmp_buf對象j。這個上下文包括程序存放位置、棧和框架指針,其它重要的寄存器和內存數據。當初始化完jump的上下文,setjmp()返回0值。
2. 以後調用longjmp(j,r)的效果就是一個非局部的goto或“長跳轉”到由j描述的上下文處(也就是到那原來設置j的setjmp()處)。當作為長跳轉的目標而被調用時,setjmp()返回r或1(如果r設為0的話)。(記住,setjmp()不能在這種情況時返回0。)
通過有兩類返回值,setjmp()讓你知道它正在被怎麼使用。當設置j時,setjmp()如你期望地執行;但當作為長跳轉的目標時,setjmp()就從外面“喚醒”它的上下文。你可以用longjmp()來終止異常,用setjmp()標記相應的異常處理程序。
#include <setjmp.h> #include <stdio.h> jmp_buf j; void raise_exception(void) { printf("exception raised\n"); longjmp(j, 1); /* jump to exception handler */ printf("this line should never appear\n"); } int main(void) { if(setjmp(j) == 0) { printf("\''setjmp\'' is initializing \''j\''\n"); raise_exception(); printf("this line should never appear\n"); } else { printf("''setjmp'' was just jumped into\n"); /* this code is the exception handler */ } return 0; } /* When run yields: ''setjmp'' is initializing ''j'' exception raised ''setjmp'' was just jumped into */ 那個填充jmp_buf的函數不在調用longjmp()之前返回。否則,存儲在jmp_buf中的上下文就有問題了: jmp_buf j; void f(void) { setjmp(j); } int main(void) { f(); longjmp(j, 1); /* logic error */ return 0; }
所以,你必須把setjmp()處理成只是到其所在位置的一個非局部跳轉。
Longjmp()和setjmp()聯合體運行於異常生命期的2和3階段。longjmp(j,r)產生異常對象r(一個整數),並且作為返回值傳送到setjmp(j)處。實際上,setjmp()函數通報了異常r。
下面這個例子採用switch,能更好的展現這對函數的功能:
#include <setjmp.h> #include <stdio.h> jmp_buf j; void raise_exception(void) { printf("exception raised\n"); longjmp(j, 3); /* jump to exception handler case 3 */ printf("this line should never appear\n"); } int main(void) { switch (setjmp(j)) { case 0: printf("''setjmp'' is initializing ''j''\n"); raise_exception(); printf("this line should never appear\n"); case 1: printf("Case 1\n");break; case 2: printf("Case 2\n");break; case 3: printf("Case 3\n");break; default: break; } return 0; }
- 詞條統計
-
- 瀏覽次數:次
- 編輯次數:14次歷史版本
- 最近更新: JD萤火虫003