Traditional C language Exception Handling Mechanism
In traditional C language Exception Handling, generally, by setting different return values or setting a global variable value indicating an error, the caller may be able to execute normally or encounter various errors, exceptions, warnings, and so on. The caller determines whether an exception has occurred and processes the exception based on the returned value of the caller. The following is a simple example of this processing method:
fun1(){....int result=fun2();switch(result){case 1 ....case 2 ........}....}fun2(){.... .... return -1;........ return 1;....}
More Reasonable Exception Handling Mechanism
In the traditional C language exception handling mechanism, if an exception needs to be transmitted by level, the return values of each lower-layer interface should be determined at each layer, and corresponding error handling code should be written. Errors that cannot be processed at this layer must be uploaded to the top-layer interface for processing. In such a layer-by-layer call, when there are many layers, errors will be passed up layer by layer, and a lot of code needs to be written, causing a lot of trouble to the programmer and easy to make mistakes. In addition, a large number of error handling codes can reduce the readability of the main interface processes. Despite continuous checks and debugging, an error is a small probability event, but it needs to be determined at each layer, affecting efficiency.
Therefore, we need to reflect on the exception handling mechanism we need in large-scale C Projects? For example, the try/catch/throw Exception Handling Mechanism in Java and C ++ is more effective. When an error occurs, you can immediately jump to the high-level interface capable of handling the error without passing the exception layer by layer.
Implementation Details
In C, we can use setjmp/longjmp to implement a mechanism similar to C ++ exception handling.
Their prototype is: int setjmp (jmp_buf env );
Void longjmp (jmp_buf ENV, int Val );
To use setjmp/longjmp, you must add the header file setjmp. H to the program. Setjmp () is used to save the content in the system stack in the buffer zone envbuf. The returned value of this macro is 0. Longjmp () redirects the program to the last time setjmp () is called, and then the following statement is re-executed. However, the second parameter of longjmp () passes a value to setjmp (). The value is the return value of setjmp () after longjmp () is called, in this way, different return values are used to distinguish the first call of setjmp.
It should be noted that setjmp/longjmp can be used across functions, so they can be used to implement an exception handling mechanism at the cross-function call level.
The following is a simple example:
We have three small files, Main. c file1.c file2.c, which are listed below:
int main(){jmp_buf main_stat;if(setjmp(error_stat)!=0){printf(" error in main \n");return -1;}file1();return 0;}
int file1(){jmp_buf file1_stat;memcpy(&file1_stat,&error_stat,sizeof(file1_stat));if(setjmp(error_stat)!=0){printf(" error in file1 \n");memcpy(&error_stat,&file1_stat,sizeof(file1_stat));longjmp(error_stat,1);}file2();}
int file2(){jmp_buf file2_stat;memcpy(&file2_stat,&error_stat,sizeof(file2_stat));if(setjmp(error_stat)!=0){printf(" error in file2 \n");memcpy(&error_stat,&file2_stat,sizeof(file2_stat));longjmp(error_stat,1);}printf(" start error \n");longjmp(error_stat,1);}
Compile and run them. The output result is:
Start Error
Error in file2
Error in file1
Error in main
This is just a simple example, and the code is passed by hierarchy, and the code is not passed by hierarchy.
Summary
By using setjmp/longjmp, you can simulate the Exception Handling Mechanism of C ++ level transfer in C. This implementation method is highly efficient, and exception handling can be well implemented in large-scale engineering projects, reducing the complexity of the program.