ç多行宏:做/时(0)VS范围块 [英] C multi-line macro: do/while(0) vs scope block
问题描述
可能显示的文件:
<一href=\"http://stackoverflow.com/questions/923822/whats-the-use-of-do-while0-when-we-define-a-macro\">What’s利用做,而(0)当我们定义一个宏?
<一href=\"http://stackoverflow.com/questions/154136/why-are-there-sometimes-meaningless-do-while-and-if-else-statements-in-c-c-macr\">Why在那里,有时毫无意义的do / while和如果C / else语句/ C ++宏?
做{&hellip; }而(0)有什么好处?
块引用>我见过一些多行C宏被包装在里面做/而(0)循环,如:
#定义FOO \\
做{\\
do_stuff_here \\
do_more_stuff \\
}而(0)什么是写code这种方式,而不是使用基本块的好处(如果有的话):
#定义FOO \\
{\\
do_stuff_here \\
do_more_stuff \\
}
解决方案<一个href=\"http://bytes.com/groups/c/219859-do-while-0-macro-substitutions\">http://bytes.com/groups/c/219859-do-while-0-macro-substitutions
安德烈Tarasevich:
使用'做/而版本是使宏这将对整个构思
扩展成一个普通的语句,而不是成为一个复合语句。这是
为了使使用的函数式进行宏均匀的
在所有情况下使用的普通功能。考虑以下code小品
如果(小于条件&gt;)
富(一);
其他
杆(一);在这里'富'和'酒吧'是普通的功能。现在想象一下,你会
喜欢的上述性质的宏替换函数'富'如果(小于条件&gt;)
CALL_FUNCS(一);
其他
杆(一);现在,如果你的宏按照定义的第二种方法
(只是'{'和'}')在code将不再编译,因为真
由复合语句psented'如果',现在重新$ P $的分支。当你
把一个';'该复合语句后,你完成整个如果
声明中,从而成为孤儿的'其他'分支(因此编译错误)。要解决此问题的方法之一是要记住不要把';'后
宏调用如果(小于条件&gt;)
CALL_FUNCS(一)
其他
杆(一);这将编译并达到预期效果,但这并不统一。该
更优雅的解决方案是确保宏观扩展到正规
声明中,不进一家化合物中的一个。实现的一个方法是定义
宏如下:的#define CALL_FUNCS(X)\\
做{\\
func1的(X); \\
FUNC2(X); \\
FUNC3(X); \\
}而(0)现在这个code
如果(小于条件&gt;)
CALL_FUNCS(一);
其他
杆(一);将编译没有任何问题。
但是,请注意我的定义之间的微小但重要的区别
的CALL_FUNCS
,并在邮件中的第一个版本。我没放;
在},而(0)
。把一个;
在该定义的结尾
马上会打败使用的整个点做/同时,使
宏观pretty多相当于复合语句版本。我不知道为什么code您的作者在原始报价
消息把这个;
在而(0)
。在这种形式这两种变体
当量。背后使用做/而版本是不是整个想法
包括这最后的;
进入宏(我解释的原因
以上)。Possible Duplicates:
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?I've seen some multi-line C macros that are wrapped inside a do/while(0) loop like:
#define FOO \ do { \ do_stuff_here \ do_more_stuff \ } while (0)What are the benefits (if any) of writing the code that way as opposed to using a basic block:
#define FOO \ { \ do_stuff_here \ do_more_stuff \ }
解决方案http://bytes.com/groups/c/219859-do-while-0-macro-substitutions
Andrey Tarasevich:
The whole idea of using 'do/while' version is to make a macro which will expand into a regular statement, not into a compound statement. This is done in order to make the use of function-style macros uniform with the use of ordinary functions in all contexts.
Consider the following code sketch
if (<condition>) foo(a); else bar(a);
where 'foo' and 'bar' are ordinary functions. Now imagine that you'd like to replace function 'foo' with a macro of the above nature
if (<condition>) CALL_FUNCS(a); else bar(a);
Now, if your macro is defined in accordance with the second approach (just '{' and '}') the code will no longer compile, because the 'true' branch of 'if' is now represented by a compound statement. And when you put a ';' after this compound statement, you finished the whole 'if' statement, thus orphaning the 'else' branch (hence the compilation error).
One way to correct this problem is to remember not to put ';' after macro "invocations"
if (<condition>) CALL_FUNCS(a) else bar(a);
This will compile and work as expected, but this is not uniform. The more elegant solution is to make sure that macro expand into a regular statement, not into a compound one. One way to achieve that is to define the macro as follows
#define CALL_FUNCS(x) \ do { \ func1(x); \ func2(x); \ func3(x); \ } while (0)
Now this code
if (<condition>) CALL_FUNCS(a); else bar(a);
will compile without any problems.
However, note the small but important difference between my definition of
CALL_FUNCS
and the first version in your message. I didn't put a;
after} while (0)
. Putting a;
at the end of that definition would immediately defeat the entire point of using 'do/while' and make that macro pretty much equivalent to the compound-statement version.I don't know why the author of the code you quoted in your original message put this
;
afterwhile (0)
. In this form both variants are equivalent. The whole idea behind using 'do/while' version is not to include this final;
into the macro (for the reasons that I explained above).这篇关于ç多行宏:做/时(0)VS范围块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!