setjump和longjump
生活随笔
收集整理的這篇文章主要介紹了
setjump和longjump
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
int setjmp( jmp_buf env );
void longjmp( jmp_buf env, int value );
#???? setjmp(j)設(shè)置“jump”點(diǎn),用正確的程序上下文填充jmp_buf 對象j。這個上下文包括程序存放位置、棧和框架指針,其它重要的寄存器和內(nèi)存數(shù)據(jù)。當(dāng)初始化完jump 的上下文,setjmp()返回0 值。對setjmp函數(shù)的調(diào)用時,會保存程序當(dāng)前的堆棧環(huán)境到env參數(shù)中;
#?????????? ? 以后調(diào)用longjmp(j,r)的效果就是一個“長跳轉(zhuǎn)”到由j 描述的上下文處(也就是到那原來設(shè)置j 的setjmp()處)。當(dāng)作為長跳轉(zhuǎn)的目標(biāo)而被調(diào)用時,setjmp()返回r 或1(如果r 設(shè)為0 的話)。(記住,setjmp()不能在這種情況時返回0。
????? 通常, 用longjmp()來終止異常,用setjmp()標(biāo)記相應(yīng)的異常處理程序, 在調(diào)用setjmp的函數(shù)返回之前,調(diào)用longjmp,否則結(jié)果不可預(yù)料。
在使用longjmp時,請遵守以下規(guī)則或限制:
$???? 不要假象寄存器類型的變量將總會保持不變。在調(diào)用longjmp之后,通過setjmp所返回的控制流中,例程中寄存器類型的變量將不會被恢復(fù)。
$???? 不要使用longjmp函數(shù),來實(shí)現(xiàn)把控制流,從一個中斷處理例程中傳出,除非被捕獲的異常是一個浮點(diǎn)數(shù)異常。在后一種情況下,如果程序通過調(diào)用_fpreset函數(shù),來首先初始化浮點(diǎn)數(shù)包后,它是可以通過longjmp來實(shí)現(xiàn)從中斷處理例程中返回。
$???? 在C++程序中,小心對setjmp和longjmp的使用,應(yīng)為setjmp和longjmp并不能很好地支持C++中面向?qū)ο蟮恼Z義。因此在C++程序中,使用C++提供的異常處理機(jī)制將會更加安全。?
#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);
}
總結(jié)
以上是生活随笔為你收集整理的setjump和longjump的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C/C++中的运算符优先级总结
- 下一篇: C++的四种强制类型转换