c mock try catch

Non-local jump statements---setjmp and longjmp functions. Non-local means that this is not a jump implemented by an ordinary C language goto statement within a function, but skips several call frames on the stack and returns to a function on the current function call path.
#include <setjmp.h>
Int setjmp(jmp_buf env);
   Return value: 0 if called directly, non-0 if returned from longjmp call
Void longjmp(jmp_buf env, int val);
    at the desired position Call setjmp, this location is in the main function, because the function is called directly, so its return value is 0. The type of the setjmp parameter evn is a special type jmp_buf, this data type is some form of array, which is stored in the call All information that can be used to restore the stack state during longjmp. Because the env variable needs to be referenced in another function, the canonical way of doing it is to define the env variable as a global variable.
   When an error is detected, the longjmp function is called with two arguments, the first is the env used when calling setjmp, and the second is val with a non-zero value, which will be the value returned from setjmp. The reason for using the second parameter is that there can be multiple longjmps for one setjmp.
    Below we can see a simple example
:

#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
#include <string.h>

void fun1(void);
void fun2(void);
 jmp_buf jmpbuffer;
void main(void)
{
    int i = 0;
    int j = 0;
    i = setjmp(jmpbuffer);
    if(i==0)
    {
        printf("first run/n");
        fun1();
        fun2();
    }
   else
   {
     switch(i)
     {
       
     case 1:
       printf("In fun1 /n");
     break;
   case 2:
     printf("In fun2/n");
     break;
   default:
     printf("unkown error/n");
     break;
     }
          exit(0);
   }
    return 1;


void fun1(void)
{
    char *s = "hello";
    char *s1 = "Hello";
    if(strcmp(s,s1)!=0)
    longjmp(jmpbuffer,1);
}

void fun2(void)
{
    char *s = "world";
    if(strcmp(s,"World")!=0)
    longjmp(jmpbuffer,2);
}

The result of running this function is:

root@root:~/program/test_program$ ./jmp_test
first run
In fun1

   When using longjmp to jump to setjmp, the program exits actively! Equivalent to throwing an exception to exit! In fact, these two functions can simulate abnormal functions in C++:
when using setjmp and longjmp, pay attention to the following points:
  1. When setjmp and longjmp are used in combination, they must have a strict order of execution, that is, call the setjmp function first, and then Call the longjmp function to restore the previously saved "program execution point". Otherwise, if the longjmp function is executed before the setjmp call, the execution flow of the program will be unpredictable, and it is easy to cause the program to crash and exit
 . 2. Do not assume that the variable of the register type will always remain unchanged. After calling longjmp, the variables of register type in the program will not be restored in the control flow returned by setjmp. The variable of the register type means that in order to improve the running efficiency of the program, the variable is not stored in the memory, but is directly stored in the register. Variables of register type are generally temporary variables. In C language, they are defined by register, or directly embedded in assembly code programs. variables of this type.
     longjmp must come after the setjmp call, and longjmp must be within the scope of setjmp. Specifically, use setjmp in a function to initialize a global label, and then call longjmp anywhere else to jump to the execution of the next statement in setjmp as long as the function never returns. In fact, the setjmp function saves the local environment where the call occurs in a jmp_buf structure. As long as the corresponding memory in the calling function has not been released (the local memory is invalid when the function returns), then when calling longjmp, you can The saved jmp_buf parameters are restored to the place where setjmp is executed.

 

Example: https://github.com/FredericGuo/CoffeeCatch.JNI

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=327075775&siteId=291194637