do { ... } while(0)是C/C++中常见的定义方式,使用它构造后的宏定义不会受到大括号、分号等的影响,总是会按你期望的方式调用运行。

一、错误引出

以下宏定义:

#define f(a,b) a(a); b(b)

对于语句f(1,2);,宏定义将会替换成:

a(1); b(2);

这条语句在这里这不会有问题,但是对于以下调用就会产生问题:

if (1) 
    f(1, 2);
else
    print(...);

经过宏替换后语句会变成:

if (1)
    a(1); b(2);
else
    print(...);

由于if后面没有带括号且连续带了两条语句,导致else部分编译出错。

二、使用大括号包裹宏

如果使用大括号把宏括起来:

#define f(a,b) {a(a); b(b);}

对于上面的调用,该代码片段会被替换成:

if (1)
    {a(1); b(2);};
else
    print(...);

else前面多了一个分号,也会导致语法错误。

最后修改:2018 年 05 月 07 日
如果觉得我的文章对你有用,请随意赞赏