写点什么

什么?C 语言也能 try...catch!

发布于: 刚刚

现代编程语言,基本都提供了 try...catch 语法,用于进行程序逻辑的异常处理。


为什么要用 try...catch?


我们来看一下常规的程序写法:


int biz_xxx(...) {	// step1: do logic1	....	if (ret != 0) {		// 错误处理1		...	}
// step2: do logic2 ... if (iret != 0) { // 错误处理2 ... }
// step3: do logic3 ... if (iret != 0) { // 错误处理3 ... }
......}
复制代码


从上面的代码,我们可以看出,正常的业务处理过程中,每个步骤都会判断是否失败,如果失败,则进行相应的错误处理,每种错误的处理代码可能有所不同。这样,正常的业务流程,与错误处理的代码混杂在一起。在一个大型软件中,业务正常逻辑处理和错误处理都可能非常复杂,代码量也可能很大,这样混杂在一起后,业务正常的逻辑主线非常不清晰,代码阅读起来比较困难。


因此,一些更为强大的编程语言,都提供了 try ... catch 语法,将正常业务流程与异常处理分开,使得代码的可阅读性、可理解性大大提高。


采用 try ... catch 语法,程序的写法变为:


int biz_xxx(...) {	try {		// step1: do logic1		....
// step2: do logic2 ...
// step3: do logic3 ... } catch (exception1) { // 错误处理1 } catch (exception1) { // 错误处理2 } catch (others) { // 错误处理3 }}
复制代码


看看,这样是不是代码阅读起来非常清晰了!


C 语言本身并不支持 try ... catch 这样的语法。但我们可以使用 C 语言的宏功能,自定义几个宏,用 goto 语句和函数内 Label 进行跳转,从而实现函数内 try ... catch 这样的写法。


宏定义如下:


#define TRY(condition) \    do {    \        if (!(condition)) goto FINISH_LABEL;    \    } while(0)
#define TRY_THROW(condition, exception_name) \ do { \ if (!(condition)) goto exception_name; \ } while(0)
#define THROW(exception_name) goto exception_name;
#define CATCH(exception_name) \ goto FINISH_LABEL; \ exception_name:

#define FINALLY \ FINISH_LABEL:
复制代码


用以上宏,编写业务代码,示例如下:


int biz_xxx(...) {	int fd = -1;	int read_len = 0;	int write_len = 0;
// step1: do logic1 TRY((fd = open(...)) != -1); ....
// step2: do logic2 TRY_THROW((read_len = read(fd, ....)) >= 0, READ_ERROR); ...
// step3: do logic3 TRY_THROW((write_len = write(fd, ....)) > 0, WRITE_ERROR); ...
CATCH(READ_ERROR) { // 错误处理1 } CATCH(WRITE_ERROR) { // 错误处理2 }
FINALLY { // .... }}
复制代码


这种写法,将正常业务逻辑与错误处理分开,使得代码非常清晰,易于维护!


我的微信号是 实力程序员,欢迎大家关注我。

发布于: 刚刚阅读数: 2
用户头像

实力程序员,用实力证明自己 2014.12.31 加入

70后码农一枚,超过20年一线开发和管理经验,酷爱编程,探求技术原本

评论

发布
暂无评论
什么?C语言也能try...catch!