下午读了一篇名为《详解C的异常处理机制》的博文,才知道在C语言中,除了使用goto进行异常处理外,还可以使用setjmp和longjmp配合实现异常处理,而且比goto更加方便。如果利用C语言做一些宏定义,可以实现类似C++、Java等语言的try-catch结构。
以下是根据该文介绍,写的关于try-catch的一些宏定义:
#ifndef __EXCEPION_H__
#define __EXCEPION_H__
#include
/// 异常标记
typedef struct tagExcepSign
{
jmp_buf _StackInfo; // 保存异常处理入口的堆栈信息
int _ExcepType; // 异常类型,0表示无异常,异常类型号一般取小于0的数
} ExcepSign;
/// 获取异常类型号
#define ExcepType(ExcepSign) ((ExcepSign)._ExcepType)
/// 可能抛出异常的代码块
#define Try(ExcepSign) if ( ((ExcepSign)._ExcepType = setjmp((ExcepSign)._StackInfo)) == 0 )
/// 捕获特定异常
#define Catch(ExcepSign, ExcepType) else if ((ExcepSign)._ExcepType == (ExcepType))
/// 捕获所有可能异常
#define CatchElse(ExcepSign) else if((ExcepSign)._ExcepType < 0)
/// 抛出异常
#define Throw(ExcepSign, ExcepType) longjmp((ExcepSign)._StackInfo, ExcepType)
#endif /* __EXCEPION_H__ */
下面的C代码使用了上述宏定义实现异常处理:
#include
#include "exception.h"
void ExceptionTest(int ExpType)
{
ExcepSign Ex;
// 异常类型号用负值表示
ExpType = ExpType > 0 ? -ExpType : ExpType;
Try(Ex) {
if (ExpType < 0) {
Throw(Ex, ExpType);
}
else {
printf("没有异常\n");
}
} Catch(Ex, -1) {
printf("异常类型:-1\n");
} Catch(Ex, -2) {
printf("异常类型:-2\n");
} CatchElse(Ex) {
printf("异常类型:未知(%d)\n", ExcepType(Ex));
}
}
void Test(void)
{
ExceptionTest(0); // 无异常
ExceptionTest(1); // 异常1
ExceptionTest(2); // 异常2
ExceptionTest(3); // 异常3
}