do { ... } while(0)
是C/C++中常见的定义方式,使用它构造后的宏定义不会受到大括号、分号等的影响,总是会按你期望的方式调用运行。
一、错误引出
以下宏定义:
1 |
#define f(a,b) a(a); b(b) |
对于语句f(1,2);
,宏定义将会替换成:
1 |
a(1); b(2); |
这条语句在这里这不会有问题,但是对于以下调用就会产生问题:
1 2 3 4 |
if (1) f(1, 2); else print(...); |
经过宏替换后语句会变成:
1 2 3 4 |
if (1) a(1); b(2); else print(...); |
由于if后面没有带括号且连续带了两条语句,导致else
部分编译出错。
二、使用大括号包裹宏
如果使用大括号把宏括起来:
1 |
#define f(a,b) {a(a); b(b);} |
对于上面的调用,该代码片段会被替换成:
1 2 3 4 |
if (1) {a(1); b(2);}; else print(...); |
else
前面多了一个分号,也会导致语法错误。
评论