C多行macros:do / while(0)vs scope block

可能重复:
当我们定义一个macros的时候,(0)有什么用呢?
为什么在C / C ++macros中有没有意义的do / while和if / else语句?
做{…} while(0)有什么好处?

我已经看到了一些多线C语言macros,这些macros被封装在一个do / while(0)循环中,如下所示:

 #define FOO \
  做{\
     do_stuff_here \
     do_more_stuff \
   (0)

与使用基本块相比,以这种方式编写代码有什么好处(如果有的话):

 #define FOO \
   {\
     do_stuff_here \
     do_more_stuff \
   }

http://bytes.com/groups/c/219859-do-while-0-macro-substitutions

安德烈·塔拉泽维奇:

使用“do / while”版本的整个想法是制作一个扩展为正则语句的macros,而不是复合语句。 这样做是为了在所有上下文中使用普通函数来使用函数式macros。

考虑下面的代码草图

if (<condition>) foo(a); else bar(a); 

“富”和“酒吧”是普通的function。 现在想象一下,你想用上面的macros来replace函数'foo'

 if (<condition>) CALL_FUNCS(a); else bar(a); 

现在,如果你的macros是按照第二种方法定义的(就是'{'和'}'),代码将不再编译,因为'if'的'true'分支现在由一个复合语句表示。 而当你把一个“;” 在这个复合语句之后,你完成了整个'if'语句,从而孤立了'else'分支(因此编译错误)。

解决这个问题的一个办法就是记住不要把';' macros观“调用”

 if (<condition>) CALL_FUNCS(a) else bar(a); 

这将按预期进行编译和工作,但这不是一致的。 更优雅的解决scheme是确保macros扩大到一个正规的声明,而不是复合。 实现这一目标的一个方法是如下定义macros

 #define CALL_FUNCS(x) \ do { \ func1(x); \ func2(x); \ func3(x); \ } while (0) 

现在这个代码

 if (<condition>) CALL_FUNCS(a); else bar(a); 

将编译没有任何问题。

但是,请注意我的CALL_FUNCS定义和消息中的第一个版本之间的小而重要的区别。 我没有把一个; } while (0) 。 放一个; 在这个定义的末尾,将会立即击败使用“do / while”的整个点,并且使这个macros与复合语句版本非常相似。

我不知道为什么你在原始信息中引用的代码的作者是这样写的; while (0) 。 在这种forms下,两种变体是等价的。 使用“do / while”版本的整个想法是不包括这个最后的; 进入macros观(因为我上面解释的原因)。