今天碰到一个判断错误返回的宏,IF_FAILED_RETURN_XXX(result),之前没有细究,顾名思义地使用着,而今天特地进去看了下,发现该宏如下:
#define IF_FAIL_RETURN_XXX(result) \
do \
{ \
... \
}while(0)
瞬间内牛满面……想起大学时阅读linux内核源码过程中,第一次遇到这种用法时觉得很是惊艳。
为什么会出现do{...}while(0)呢?
首先是基本的宏用在if判断语句时会出现问题:
#define SomeMacro(x) \
expr1_doSth_with(x); \
expr2_doSth_with(x);
//使用
if(x)
SomeMacro(x);
else
x++;
//展开
if(x)
expr1_doSth_with(x);
expr2_doSth_with(x);;
else
x++;
再为这个宏添加上一个花括号来包容语句块:
#define SomeMacro(x) \
{ \
expr1_doSth_with(x); \
expr2_doSth_with(x); \
}
//使用
if(x)
SomeMacro(x);
else
x++;
//展开
if(x)
{
expr1_doSth_with(x);
expr2_doSth_with(x);
};
else
x++;
这种情况下使用宏就要小心这个分号了。可能有人觉得不要添加那个括号就好了,不过这样看起来很奇怪:
#define SomeMacro(x) \
{ \
expr1_doSth_with(x); \
expr2_doSth_with(x); \
}
//使用
if(x)
SomeMacro(x)
else
x++;
看到上面的if-else语句,是不是总觉得很别扭呢? :) C++使用者总有个分号结尾瘾……
最后一点看似不重要却也挺重要的作用是:对IDE良好。如果将分号放到宏里面,IDE检查不到行末的分号,会造成缩进错误。这一点其实也可以归于上一句话,C++的开发环境有分号结尾瘾……LOL