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观(因为我上面解释的原因)。