??????????????????????????????????????????????
?????????????setjmp??longjmp
??????C?????У????????setjmp??longjmp?γ?????????????????????????setjmp??????????????longjmp??????
????setjmp??longjmp??C?????????е??????????????C????????????????????????abort()??exit()????goto??俴?????????????????з?????????????goto???????????????????????????????????????????????????????????????????????????????????????main???У???
?????????????????C??????????setjmp()??longjmp()????????????е?????????goto???á?????<setjmp.h>????????Щ?????????????jmp_buf?????????
?????????????
????int setjmp(jmp_buf env) ?????????jmp_buf??????????????????????????????????????????????????????env????????????????env????longjmp??á???????setjmp?????÷????setjmp??????0????????longjmp???????????????????setjmp??????????
????void longjmp(jmp_buf env?? int value) ???env???????????е?????????????????env???????????????????setjmp?????????????檔value?????longjmp?????setjmp??longjmp?????????????setjmp???????????У????setjmp????????ɡ????value?????longjmp?????setjmp???????1??????setjmp???????value??
????????????
????jmp_buf ????????????磺struct int[16]??struct __jmp_buf_tag????????????????????????????
????jmp_buf ????壺
????typedef struct _jmp_buf
????{
????int _jp[_JBLEN+1];
????} jmp_buf[1];
????????? setjmp.h ?????ж??壬????? struct ???????????顣???????????? jmp_buf ???????????????????????????????????????????????????????
?????????????
????1.setjmp(j)????“jump”?????????????????????jmp_buf????j????????????????????λ?á?????????????????????????????????????????jump?????????setjmp()????0???
????2. ??????longjmp(j??r)??Ч?????????????goto??“?????”????j????????????????????????????j??setjmp()???????????????????????????????setjmp()????r??1?????r???0??????????????setjmp()??????????????????0????
??????????????????setjmp()???????????????????á???????j???setjmp()????????????У?????????????????????setjmp()??????“????”??????????????????longjmp()???????????setjmp()?????????????????
????????????http://www.cnblogs.com/archimedes/p/c-exception-assert.html????????????????
????????????????
????#include <stdio.h>
????#include <setjmp.h>
????static jmp_buf buf;
????void second(void) {
????printf("second ");         // ???
????longjmp(buf??1);             // ????setjmp?????? - ???setjmp??????1
????}
????void first(void) {
????second();
????printf("first ");          // ????????е?????
????}
????int main() {  
????if ( ! setjmp(buf) ) {
????first();                // ??????????setjmp????0
????} else {                    // ??longjmp??????setjmp????1???????????
????printf("main ");       // ???
????}
????return 0;
????}
???????н????
????second
????main
???????????У?setjmp??????????????????????try??longjmp??????????throw?????????????????setjmp????????
????#include <stdio.h>
????#include <stdlib.h>
????#include <string.h>
????#include <setjmp.h>
????void first(void);
????void second(void);
????static jmp_buf exception_env;
????static int exception_type;
????int main(void) {
????void *volatile mem_buffer;
????mem_buffer = NULL;
????if (setjmp(exception_env)) {
????/* ??????е????????????*/
????printf("first failed?? exception type %d "?? exception_type);
????} else {
????printf("calling first ");
????first();
????mem_buffer = malloc(300); /* ??????? */
????printf("%s"??strcpy((char*)mem_buffer?? "first succeeded!")); /* ... ??????? */
????}
????if (mem_buffer)
????free((void*) mem_buffer); /* С???????? */
????return 0;
????}
????void first(void) {
????jmp_buf my_env;
????printf("calling second ");
????memcpy(my_env?? exception_env?? sizeof(jmp_buf));
????switch (setjmp(exception_env)) {
????case 3:
????/* ??????е?????????? */
????printf("second failed with type 3 exception; remapping to type 1. ");
????exception_type = 1;
????default:
????memcpy(exception_env?? my_env?? sizeof(jmp_buf)); /* restore exception stack */
????longjmp(exception_env?? exception_type); /* continue handling the exception */
????case 0:
????/* normal?? desired operation */
????second();
????printf("second succeeded ");  /* not reached */
????}
????memcpy(exception_env?? my_env?? sizeof(jmp_buf)); /* restore exception stack */
????}
????void second(void) {
????printf("entering second " );
????exception_type = 3;
????longjmp(exception_env?? exception_type);
????printf("leaving second ");
????}
???????н????
????calling first
????calling second
????entering second
????second failed with type 3 exception; remapping to type 1.
????first failed?? exception type 1
???????
????Except????????к?????????а????setjmp??longjmp?????????????????????????????
????????Except_T?????????????????:
????#ifndef EXCEPT_INCLUDED
????#define EXCEPT_INCLUDED
????#include <setjmp.h>
????#define T Except_T
????typedef struct T {
????char *reason;
????} T;
????Except_T??????????Σ???????????????????????????????????????δ?????????????????????????
??????????????????????????????????????????????????????????????????????e???????????????????????
????#define RAISE(e) Except_raise(&(e)?? __FILE__?? __LINE__)
????void Except_raise(const T *e?? const char *file??int line);
???????????????TRY-EXCEPT??TRY-FINALLY???????????????????????ú????????????????????????????????????????????????
????TRY-EXCEPT???????
????TRY
????S
????EXCEPT(e1)
????S1
????EXCEPT(e2)
????S2
????……
????EXCEPT(en)
????Sn
????ELSE
????S0
????END_TRY
??????????????
????int Allocation_handle = 0;
????jmp_buf Allocate_Failed;
????void *allocate(unsigned n)
????{
????void *new = malloc(n);
????if(new)
????return new;
????if(Allocation_handle)
????longjmp(Allocate_Failed?? 1);
????assert(0);
????}
????char *buf;
????Allocation_handle = 1;
????if(setjmp(Allocate_Failed)) {
????fprintf(stderr?? "cound't allocate the  buff ");
????exit(EXIT_FAILURE);
????}
????buf = allocate(4096);
????Allocation_handle = 0;