可能的重复项: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?
我已经看到了一些多行C宏,它们包裹在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'版本的整个想法是创建一个宏扩展为常规语句,而不是复合语句。这是为了使函数样式宏与在所有情况下都使用普通功能。
请考虑以下代码草图
if (<condition>)
foo(a);
else
bar(a);
其中'foo'和'bar'是普通函数。现在想象你会想要用上述性质的宏替换功能'foo'
if (<condition>)
CALL_FUNCS(a);
else
bar(a);
现在,如果您的宏是根据第二种方法定义的,(仅{
和}
)该代码将不再编译,因为'true'现在,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'的意义,并使该宏几乎等同于复合语句版本。
我不知道为什么您在原始文件中引用的代码的作者消息将此;
放在while (0)
之后。这种形式的两个变体都是当量。使用“ do / while”版本的整个思想不是将最后的;
包含到宏中(出于我解释的原因以上)。