淺談setjmp與longjmp

來源:互聯網
上載者:User
  在C語言中,用於跳轉的goto語句,只能夠用在同一個函數內部的跳轉。而setjmp 與 longjmp的結合使用,卻可以實現在不同程式之間的跳轉。讓我們先來看一下函數原型吧:
#include <setjmp.h>int setjmp(jmp_buf env) 
Returns: 0 if called directly, nonzero if returning from a call to longjmp.
 
void longjmp(jmp_buf env, int val);    這兩個函數都要包含標頭檔setjmp.h。而且它們在處理出現在深層函數嵌套的錯誤情況時很有用處。
    setjmp這個函數很有意思,雖然是一個函數,可是卻可以返回兩個不同的值。當第一次直接調用setjmp時,傳回值為0。當從longjmp函數返回時,setjmp函數的傳回值為longjmp的第二個參數的值。
    那麼在什麼地方調用setjmp呢?我們希望當從longjmp函數返回時,程式從哪裡接著開始運行,我們就在哪裡調用setjmp。看個小執行個體,你就明白是怎麼回事了。    #include<stdio.h>
    #include<setjmp.h>    jmp_buf ebuf;
    void f2(void);
   int main(void)
   {
     int i;
     printf("1");
     i=setjmp(ebuf);
     if(i==0)                                              //第一次執行到這裡時,值為0,所以接下來執行f2()
     {
   f2();
   printf("This will not be printed."); 
     }
     printf("%d",i);                                    //由於從longjmp返回時,i=3,不執行if,所以執行該行
     return 0;
}
   void f2(void)
{
   printf("2");                                          
   longjmp(ebuf,3);  //longjmp函數返回,回到setjmp的位置,使得setjmp傳回值為3// 把  i=setjmp(ebuf);放在printf("1")後,即可觀察

    函數最後的執行結果為123,嘻嘻。      longjmp注意:
  1.不要假象寄存器類型的變數將總會保持不變。在調用longjmp之後,通過setjmp所返回的控制流程中,常式中寄存器類型的變數將不會被恢複。
  2.不要使用longjmp函數來實現把控制流程,從一個中斷處理常式中傳出,除非被捕獲的異常是一個浮點數異常。在後一種情況下,如果程式通過調用 _fpreset函數,來首先初始化浮點數包後,它是可以通過longjmp來實現從中斷處理常式中返回。
  3. 在C++程式中,小心對setjmp和longjmp的使用,應為setjmp和longjmp並不能很好地支援C++中物件導向的語義。因此在C++程式中,使用C++提供的異常處理機制將會更加安全。把setjmp和longjmp組合起來,原來它這麼厲害!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.