Before you scoff, consider that some exceptions betray a condition so severe that reasonable recovery is unlikely anyway. Perhaps the best example is malloc of a small object returning NULL. If the free store manager can't scrape together a few spare contiguous bytes, your C庫頭文件<stdlib.h>提供了兩個(gè)不是相當(dāng)完美的程序函數(shù):abort與exit,這些函數(shù)實(shí)現(xiàn)了異常的生命期在第4、5階段。兩者不返回它的調(diào)用者,并且結(jié)束程序。
By having two classes of return values, setjmp lets you determine how it's being used. When setting j, setjmp works as you normally expect; but as the target of a long jump, setjmp "wakes up" from outside its normal context. 假如使用longjmp來引發(fā)終止異常,setjmpgoto到正確的異常處理方法里。
#include <setjmp.h> #include <stdio.h>
jmp_buf j; void raise_exception(void) { printf("exception raised/n"); longjmp(j, 1); /* jump to exception handler */ printf("this line should never appear/n"); }
int main(void) { if (setjmp(j) == 0) { printf("'setjmp' is initializing 'j'/n"); raise_exception();//Restore context printf("this line should never appear/n"); } else { printf("'setjmp' was just jumped into/n"); /* this code is the exception handler */ } return 0; }
/* 運(yùn)行結(jié)果:
'setjmp' is initializing 'j' exception raised 'setjmp' was just jumped into */
int main(void) { double x, y, result; /* ... somehow set 'x' and 'y' ... */ errno = 0; result = pow(x, y); if (errno == EDOM) printf("domain error on x/y pair/n"); else if (errno == ERANGE) printf("range error on result/n"); else printf("x to the y = %d/n", (int) result); return 0; }
說明:errno不需要引用到對象:
int *_errno_function() { static int real_errno = 0; return &real_errno;//不需要這樣做 }
#define errno (*_errno_function())
int main(void) { errno = 0; /* ... */ if (errno == EDOM) /* ... */ } 返回值與參數(shù)