setjump和longjump

 

setjump和longjump  

int setjmp( jmp_buf env );
void longjmp( jmp_buf env, int value );
 
#     setjmp(j)設置“jump”點,用正確的程序上下文填充jmp_buf 對象j。這個上下文包括程序存放位置、棧和框架指針,其它重要的寄存器和內存數據。當初始化完jump 的上下文,setjmp()返回0 值。setjmp函數的調用時,會保存程序當前的堆棧環境到env參數中;
#             以後調用longjmp(j,r)的效果就是一個“長跳轉”到由j 描述的上下文處(也就是到那原來設置j 的setjmp()處)。當作爲長跳轉的目標而被調用時,setjmp()返回r 或1(如果r 設爲0 的話)。(記住,setjmp()不能在這種情況時返回0。
  
       通常, 用longjmp()來終止異常,用setjmp()標記相應的異常處理程序, 在調用setjmp的函數返回之前,調用longjmp,否則結果不可預料。
  在使用longjmp時,請遵守以下規則或限制:
$     不要假象寄存器類型的變量將總會保持不變。在調用longjmp之後,通過setjmp所返回的控制流中,例程中寄存器類型的變量將不會被恢復。
$     不要使用longjmp函數,來實現把控制流,從一箇中斷處理例程中傳出,除非被捕獲的異常是一個浮點數異常。在後一種情況下,如果程序通過調用_fpreset函數,來首先初始化浮點數包後,它是可以通過longjmp來實現從中斷處理例程中返回。
$     C++程序中,小心對setjmplongjmp的使用,應爲setjmplongjmp並不能很好地支持C++中面向對象的語義。因此在C++程序中,使用C++提供的異常處理機制將會更加安全。 
  #include   <conio.h>  
  #include   <setjmp.h>  
  void   RaiseException ( jmp_buf   jmpbuf)  
  {  
    printf(   "Press   a   key   to   restore   stack   environment...\n"   )   ;  
    getch()   ;  
    longjmp(jmpbuf, 1);  
}  
 
  int   main()  
  {  
    jmp_buf   jmpbuf   ;  
int   result  ;  
 
     printf(   "Save   stack   environment...\n"   )   ;  
     result   =   setjmp(jmpbuf)   ;  
if( result  ==   0  )  
{
 //Do something
 //If anything wrong.
 RaiseException(jmpbuf)  ;  
}
else// the exception handler, return by longjump, non-zero value
{  
         printf(   "longjump()   returned   %d.\n",   result   )   ;  
         exit(0)   ;  
}
  
    return   0   ;  
  }  
 程序輸出將是如下序列: 
  Saving   stack   environment...  
  Call   MyFunc()...  
  Press   a   key   torestore   stack   environment...  
setjmp()   returned   1
//Example 2
#include <stdio.h>
#include <setjmp.h>
 
jmp_buf save;
 
void main()
{
 char c;
 
 for (;; )
{
    switch ( setjmp( save )) 
{
     case 0:
printf ( "Zero returned from setjmp on setup.\n\n");   
break;              
     case 1:
printf ( "NORMAL PROGRAM OPERATION\n\n" );     
break;
     case 2:
printf ( "WARNING\n\n" );     
break;
     case 3:
 printf ( "FATAL ERROR PROGRAM TERMINATED\n\nReally Terminate? y/n: " );
                        fflush ( stdout );           
                        scanf ( "%1s", &c );
                       c  = tolower ( c );       
if ( c == 'y' ) return ( 1 );
                          printf ( "\n" );       break;
        default:     
printf ( "Should never return here.\n" );     
break;
    }
    process ();
 }
}
 
void process ()
{
 int i;
 
 printf ( "Input a number to simulate an error condition: " );
 fflush ( stdout ); scanf ( "%d", &i ); i %= 3;
 i++;               
 longjmp ( save, i);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章