今天碰到一个判断错误返回的宏,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