用C语言实现try-catch功能

用C语言实现try-catch/try-except功能

本文拟用C语言中的 signal 函数、siglongjmp 函数来实现类似python中的 try - except 功能或是C++中的 try - catch 功能。

文章目录

用C语言实现try-catch/try-except功能一、函数说明二、跳转说明三、代码示例

一、函数说明

用C语言实现C++的try-catch功能或类似python的try-except功能,主要依赖C标准库中的signal、siglongjmp和__sigsetjmp三个函数。 signal(int signum, sighandler_t handler),用于注册异常信号,只有注册过的异常信号类型,才能捕获到。参数signum是要注册的信号(异常);参数handler则是对应信号的处理函数; __sigsetjmp (struct __jmp_buf_tag __env[1], int __savemask),用于存储环境信息,也即是将调用该函数处,所在时刻的环境信息写入变量env中;注意,该函数第一次调用时,其返回值为

0

0

0。 siglongjmp (struct __jmp_buf_tag __env[1], int __val),该函数实现跨函数的跳转,它将跳转到第一次调用函数__sigsetjmp 所在的位置,并将参数__val作为__sigsetjmp 的返回值。

二、跳转说明

下面以第三部分的实例代码,简述一下整个C语言版try-catch的跳转流程,如下图:

三、代码示例

如下代码示例,通过signal、siglongjmp和__sigsetjmp三个函数实现了C语言下的try-catchg功能。我们通过在测试函数test_fun 中写入不同的异常,来测试代码功能。 未在test_fun中写入异常代码时,函数正常返回

0

0

0,如下图: 当在test_fun中加入一行,除

0

0

0 的代码时,函数返回

1

-1

−1,结果如下图: 当在test_fun中加入一行越界写的代码时,运行结果返回

1

-1

−1,如下图: 以下是整个示例的完整代码。

#include

#include

#include

#include

#include

jmp_buf env; // 定义结构体变量env,用来存储环境信息

/**@brief 信号处理函数 */

void sig_handle(int sig) { siglongjmp(env,1); }

/**@brief 注册信号捕捉 */

void sig_init(void)

{

signal(SIGABRT,sig_handle);

signal(SIGFPE,sig_handle);

signal(SIGILL,sig_handle);

signal(SIGINT,sig_handle);

signal(SIGSEGV,sig_handle);

signal(SIGTERM,sig_handle);

}

/**@brief 注销信号捕捉 */

void sig_reset(void)

{

signal(SIGABRT,SIG_DFL);

signal(SIGFPE,SIG_DFL);

signal(SIGILL,SIG_DFL);

signal(SIGINT,SIG_DFL);

signal(SIGSEGV,SIG_DFL);

signal(SIGTERM,SIG_DFL);

}

/**@brief 测试函数 */

static int test_fun(void)

{

int i = 0;

int a[3] = {1,2,3};

printf("in test fun.\n");

// i = 1/0; // 除0错误

// a[3] = 2; // 越界写异常

return 0; // 正常结束返回0

}

/**@brief 主函数 */

void main(void)

{

int err_num = 0; // 定义异常值,初始值为0;

sig_init(); // 注册信号捕获

//

switch (__sigsetjmp(env,1))

{

case 0: // 正常运行时的case

err_num = test_fun();

break;

default: // 当case 0中test_fun出现异常时,跳转到default

err_num = -1;

break;

}

sig_reset(); // 信号捕获注销

printf("err_num = %d\n",err_num); // 正常返回打印0,捕获异常打印 -1

}

Copyright © 2022 世界杯吉祥物_世界杯日本队 - ctpapi.com All Rights Reserved.