do{...} while(0)

前段时间看公司项目源码时,发现一个很有意思的地方,就是在很多宏函数定义里会出现do{...} while(0)。

#define ASSERT_ARRAY_EQ(expect, actual) do {    /
    ASSERT_EQ(sizeof(expect), sizeof(actual));    /
    for( size_t i = 0; i < sizeof(expect)/sizeof(int); i++)    /
    {    /
        ASSERT_EQ(expect[i], actual[i]);    /
    }    /
} while(0)

开始的时候百思不得其解,写不写这个循环似乎都只会跑一次,那是不是多此一举呢。后来仔细想了想,这么做在实际的工程项目中的确是非常有用的。

如果不使用do{...} while(0),在非嵌套使用的情况下,使用这个宏是不会出现什么问题的。

/* ...........code............ */
ASSERT_ARRAY_EQ(expected, actual);
/* ...........code............ */

上面这段代码里中间那一行会被宏函数直接替换。

然而,考虑下面这种情况:

if(...)
    ASSERT_ARRAY_EQ(expected, actual);
else
    ...

如果没有do{...} while(0),那么这段代码就会被替换成:

if(...)
    ASSERT_EQ(sizeof(expected), sizeof(actual)); 
for( size_t i = 0; i < sizeof(expected)/sizeof(int); i++)
{
    ASSERT_EQ(expected[i], actual[i]);
}
else
    ...

是不是看出问题了。

那有人就想,为什么不将宏函数直接放在花括号内呢,答案是这样的话可能会带来另一个问题:

if(...)
{
    ASSERT_EQ(sizeof(expected), sizeof(actual)); 
    for( size_t i = 0; i < sizeof(expected)/sizeof(int); i++)
    {
        ASSERT_EQ(expected[i], actual[i]);
    }
};
else
    ...

花括号后面会多一个分号,那你可能会说,我在if语句中使用这个宏函数时不在尾部添加分号不就好了吗,是的,这当然可以。但是,有时编程习惯使然,我们会不自觉的在一行代码后面加上分号,然后bug就找上门了...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值