ç多行宏:做/时(0)VS范围块 [英] C multi-line macro: do/while(0) vs scope block

查看:145
本文介绍了ç多行宏:做/时(0)VS范围块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


  

可能显示的文件:

  <一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 ; after while (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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆