do while(0)在开发中的使用

1、起因:

        今天看代码时,看到有个宏定义是这样的: 

#define setup_timer(timer, fn, data) \
do { \
static struct lock_class_key __key; \
setup_timer_key((timer), #timer, &__key, (fn), (data));\
} while (0)

当时比较疑问为啥这个宏定义要加个do{ }while(0),直接{}不行吗?

后来一查才发现有大学问,下面分析:

2、用do{}while(0)的原因

    最主要的就是:帮助定义复杂的宏以避免错误

举例,假如上述函数被按照下面调用:

定义如下:

#define setup_timer(timer, fn, data) \
{ \
static struct lock_class_key __key; \
setup_timer_key((timer), #timer, &__key, (fn), (data));\
} 

调用如下:

if()
    setup_timer();    ///只有1条语句,有很多人不加{};此时展开的时候多了个;导致逻辑和编译错误
else
    do sth.;

展开后是:
if()
   { 
        static struct lock_class_key __key; 
        setup_timer_key((timer), #timer, &__key, (fn), (data));
    } ;        //这里出错
else
    do sth.;

可以看到当setup_timer()展开后,最后}后面会多个“;”,这会导致if语句被截断而产生错误!!!

当用do{}while(0)时,就可以合理的规避这个书写错误!!!

说不定还有其他可能的错误就不一一举例了!!!!!

3、do{}while(0)其他秒用

 3.1 避免使用goto控制程序流

在一些函数中,我们可能需要在return语句之前做一些清理工作,比如释放在函数开始处由malloc申请的内存空间,使用goto总是一种简单的方法:

int foo()
{
    somestruct *ptr = malloc(...);

    dosomething...;
    if(error)
        goto END;
    dosomething...;
    if(error)
        goto END;
    dosomething...;
END:
    free(ptr);
    return 0;
}

将goto替换掉的一种书写方法如下:

int foo()
{
    somestruct *ptr = malloc(...);
    do
    {
        dosomething...;
        if(error)
            break;
        dosomething...;
        if(error)
            break;
        dosomething...;
    }
    while(0);

    free(ptr);
    return 0;
}

实际中经常遇到这样情况代码

  有的分支直接退出,有的分支还需后续处理这样子,考虑do{}while(0)

int foo()
{
    somestruct *ptr = malloc(...);
    do
    {
        dosomething...;
        if(error)
            break;
        dosomething...;
        if(error)
            return;          //有的分支直接退出,有的分支还需后续处理这样子,考虑do{}while(0)
        dosomething...;
    }
    while(0);

    free(ptr);
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值