可能重复:
What’s the use of do while(0) when we define a macro?
Why are there sometimes meaningless do/while and if/else statements in C/C++ macros?
do { … } while (0) what is it good for?
我见过一些包含在do / while(0)循环中的多行C宏,如:
#define FOO \ do { \ do_stuff_here \ do_more_stuff \ } while (0)
与使用基本块相反,编写代码有什么好处(如果有的话):
#define FOO \ { \ do_stuff_here \ do_more_stuff \ }
答案 0 :(得分:248)
http://bytes.com/groups/c/219859-do-while-0-macro-substitutions
Andrey Tarasevich:
使用'do / while'版本的整个想法是创建一个宏 扩展为常规语句,而不是复合语句。这是 为了使函数式宏使用而完成 在所有情境中使用普通函数。
考虑以下代码草图
if (<condition>)
foo(a);
else
bar(a);
其中'foo'和'bar'是普通函数。现在想象一下你 喜欢将函数'foo'替换为上述性质的宏
if (<condition>)
CALL_FUNCS(a);
else
bar(a);
现在,如果您的宏是按照第二种方法定义的 (只是'{'和'}')代码将不再编译,因为'true' 'if'的分支现在由复合语句表示。当你 放一个';'在这个复合语句之后,你完成了整个'if' 声明,因此孤立'else'分支(因此编译错误)。
解决此问题的一种方法是记住不要放';'后 宏“调用”
if (<condition>)
CALL_FUNCS(a)
else
bar(a);
这将按预期编译和工作,但这不统一。该 更优雅的解决方案是确保宏扩展为常规 声明,而不是复合词。实现这一目标的一种方法是定义 宏如下
#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'和make的整个过程
那个宏几乎等同于复合语句版本。
我不知道为什么你原来引用的代码的作者
消息将此;
放在while (0)
之后。在这种形式中,两种变体都是
当量。使用'do / while'版本背后的整个想法不是
将此最终;
包含在宏中(出于我解释的原因)
上文)。