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 PRogram's robustness is severely compromised, and the odds of elegant recovery are slim. C库头文件<stdlib.h>提供了两个不是相当完美的程序函数:abort与exit,这些函数实现了异常的生命期在第4、5阶段。两者不返回它的调用者,并且结束程序。
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来引发终止异常,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; }
/* 运行结果:
'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) /* ... */ } 返回值与参数