1//所需頭文件 2#include 3 4intsetjump(jmp_bufbuf) 5voidlongjump(jmp_bufbuf,inti) 6
一些朋友該說了,“我從來不用這些跳轉,免得出問題”。還是一直以來的那句話,“存在即合理”~
下面,我們來看看這兩個函數到底有什么可以推敲的東西。
1函數介紹
有研究過RTOS的朋友應該對此不難理解,setjump主要是保存當前函數調用點的現場環境(或者叫上下文),比如各種寄存器、堆棧等等,那么這些環境信息就記錄在jmp_buf所定義的buf中。
而當我們在其他位置調用longjump函數就相當于一個長跳轉,傳入之前保存在buf中的信息,即可跳回到之前setjump所調用的位置(理解為恢復setjump所保存的環境也是可以的)。
所以,這里值得注意的是,不要率先調用longjump,否則程序不知道飛去哪里了。
其實跟RTOS中進行任務切換有著異曲同工之妙。
你大概已經注意到setjump有一個返回值,其主要分為兩種情況:
當直接調用setjump函數,則返回0;
當調用longjump跳轉到setjump位置,則其返回longjump的第二個非零參數。
2跟goto有啥區別?
以前我也跟大家介紹過goto這匹野馬被馴服的方式(goto關鍵字你不知道的"那些事"(C語言提升)),在C語言中goto只能實現函數內部的跳轉,無法實現跨函數的直接跳轉,比如函數嵌套多層的跳轉等等。
當然,你也可以借助goto與函數返回配合完成函數之間的跳轉,不過那太麻煩了,所以這兩個庫函數該派上用場了。
這樣的跳轉太過于霸道,我們還是限制一下,切不可濫用,但其為異常處理代碼的模塊化帶來了福音,在非常多的開源庫中都有實際應用。
下面給大家一個參考示例 ::
1#include 2#include 3 4jmp_bufmark; 5intfperr; 6voidfpcheck(void); 7 8/********************************************* 9*Function:main 10*Description:主任務函數 11*Note:(公眾號:最后一個bug) 12*********************************************/ 13intmain(void) 14{ 15intjmpret; 16 17//記錄異常代碼與正常代碼分支位置 18jmpret=setjmp(mark); 19if(jmpret==0) 20{ 21//正常用戶程序運行 22 23} 24else 25{ 26//在正常用戶程序運行過程中發生異常 27fpcheck(); 28} 29} 30/********************************************* 31*Function:Errorhandler 32*Description:異常中斷,在正常用戶程序運行過程中發生異常處理函數 33*Note:(公眾號:最后一個bug) 34*********************************************/ 35voidErrorhandler(void) 36{ 37fperr=num; 38longjmp(mark,-1);//進行長跳轉到異常處理 39} 40 41/********************************************* 42*Function:fpcheck 43*Description:故障處理函數 44*Note:(公眾號:最后一個bug) 45*********************************************/ 46voidfpcheck(void) 47{ 48 49switch(fperr) 50{ 51caseINVALID: 52//userCode 53break; 54 55caseOVERFLOW: 56//userCode 57break; 58 59caseZERODIVIDE: 60//userCode 61break; 62default: 63break; 64} 65 66}
3局限性
這組函數除了前面介紹的注意事項,還有一個非常值得注意的點就是longjump的調用時機必須在setjump被調用的所在函數返回前。
因為setjump保存有堆棧信息等,一旦setjump的被調用的函數返回則相應的環境會被釋放,導致longjump無法在恢復到setjump調用位置,可能造成程序奔潰。
最后
好了,今天就跟大家分享這么多了,這一塊還有一些東西可以挖掘,后面再整理一下分享出來。如果你覺得有所收獲,一定記得點個贊!
原文標題:C語言中比goto還“霸道”的跳轉方式
文章出處:【微信公眾號:嵌入式ARM】歡迎添加關注!文章轉載請注明出處。
審核編輯:湯梓紅
-
寄存器
+關注
關注
31文章
5359瀏覽量
120778 -
C語言
+關注
關注
180文章
7610瀏覽量
137232 -
函數
+關注
關注
3文章
4341瀏覽量
62796 -
跳轉
+關注
關注
0文章
5瀏覽量
5983
原文標題:C語言中比goto還“霸道”的跳轉方式
文章出處:【微信號:gh_c472c2199c88,微信公眾號:嵌入式微處理器】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論