全面了解setjmp與longjmp的使用

2021-04-27 20:02:22 字數 2209 閱讀 1791

[ 2006-7-7 6:50:00 | by: 風吹雨點飄 ]

另外請特別注意,setjmp函式與longjmp函式總是組合起來使用,它們是緊密相關的一對操作,只有將它們結合起來使用,才能達到程式控制流有效轉移的目的,才能按照程式設計師的預先設計的意圖,去實現對程式中可能出現的異常進行集中處理。

與goto語句的作用類似,它能實現本地的跳轉

這種情況容易理解,不過還是列舉出乙個示例程式吧!如下:

void main( void )

else

exit(0);

}return;

}上面的例程非常地簡單,其中程式中使用到了異常處理的機制,這使得程式的**非常緊湊、清晰,易於理解。在程式執行過程中,當異常情況出現後,控制流是進行了乙個本地跳轉(進入到異常處理的**模組,是在同乙個函式的內部),這種情況其實也可以用goto語句來予以很好的實現,但是,顯然setjmp與longjmp的方式,更為嚴謹一些,也更為友善。程式的執行流如圖17-1所示。

setjmp與longjmp相結合,實現程式的非本地的跳轉void func1()

void func2()

void func3()

void main( void )

else

exit(0);

}return;

}回顧一下,這與c++中提供的異常處理模型是不是很相近。異常的傳遞是可以跨越乙個或多個函式。這的確為c程式設計師提供了一種較完善的異常處理程式設計的機制或手段。

setjmp和longjmp使用時,需要特別注意的事情

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

class test

~test()

}obj;

//注意,上面宣告了乙個全域性變數obj

void main( void )

else

exit(0);

}return;

}上面的程式執行結果,如下:

構造物件

press any key to continue

的確,上面程式崩潰了,由於在func1()函式內,呼叫了longjmp,但此時程式還沒有呼叫setjmp來儲存乙個程式執行點。因此,程式的執行流變的不可**。這樣導致的程式後果是非常嚴重的,例如說,上面的程式中,有乙個物件被構造了,但程式崩潰退出時,它的析構函式並沒有被系統來呼叫,得以清除一些必要的資源。所以這樣的程式是非常危險的。(另外請注意,上面的程式是乙個c++程式,所以大家演示並測試這個例程時,把原始檔的副檔名改為***.cpp)。

2、除了要求先呼叫setjmp函式,之後再呼叫longjmp函式(也即longjmp必須有對應的setjmp函式)之外。另外,還有乙個很重要的規則,那就是longjmp的呼叫是有一定域範圍要求的。這未免太抽象了,還是先看乙個示例,如下:

int sub_func()

else

//注意這一語句,程式有條件地退出

if (be_modify==0) exit(0);

}return jmpret;

}void main( void )

如果你執行或除錯(單步跟蹤)一下上面程式,發現它真是挺神奇的,居然longjmp執行時,程式還能夠返回到setjmp的執行點,程式正常退出。但是這就說明了上面的這個例程的沒有問題嗎?我們對這個程式小改一下,如下:

int sub_func()

else

//注意這一語句,程式有條件地退出

if (be_modify==0) exit(0);

}return jmpret;

}void main( void )

4、msdn中還做了特別的說明,「在c++程式中,小心對setjmp和longjmp的使用,因為setjmp和longjmp並不能很好地支援c++中物件導向的語義。因此在c++程式中,使用c++提供的異常處理機制將會更加安全。」雖然說c++能非常好的相容c,但是這並非是100%的完全相容。例如,這裡就是乙個很好的例子,在c++程式中,它不能很好地與setjmp和longjmp和平共處。在後面的一些文章中,有關專門討論c++如何相容支援c語言中的異常處理機制時,會做詳細深入的研究,這裡暫且跳過。

總結

全面了解setjmp與longjmp的使用

將對setjmp與longjmp的具體使用方法和適用的場合,進行乙個非常全面的闡述。另外請特別注意,setjmp函式與longjmp函式總是組合起來使用,它們是緊密相關的一對操作,只有將它們結合起來使用,才能達到程式控制流有效轉移的目的,才能按照程式設計師的預先設計的意圖,去實現對程式中可能出現的異...

全面了解 Powerset

人們期待已久的自然語言搜尋引擎 powerset 終於亮相,powerset 將改變人們從 wikipedia 搜尋和發現資料的方式。基於 parc 專利許可,以及專有的搜尋技術的 powerset 將是自然語言搜尋技術的一種突破,它可以就任何主題或領域,從 wikipedia 的文章中抓取句子的含...

CSS margin全面了解

一 margin可以為負值 在盒模型中,內容區的width height padding border都不能為負值,但是margin例外,它可以為負值。關於margin負值的使用技巧,了解不多,日後有機會再補充,此處先貼乙個經典應用,margin left負值結合浮動實現不改變dom結構的流體布局。...