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

举报
实力程序员 发表于 2021/07/08 14:06:31 2021/07/08
【摘要】 现代编程语言,基本都提供了try...catch 语法,用于进行程序逻辑的异常处理。为什么要用try...catch? 我们来看一下常规的程序写法:int biz_xxx(...) { // step1: do logic1 .... if (ret != 0) { // 错误处理1 ... } // step2: do logic2...

现代编程语言,基本都提供了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 (exception2) {
        // 错误处理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 {
        // ....
    }
}

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

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

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。