【问题标题】:C multi-line macro: do/while(0) vs scope block [duplicate]C多行宏:do/while(0) vs scope block [重复]
【发布时间】:2010-11-07 05:21:00
【问题描述】:

可能的重复:
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_stuff_here \ 做更多的东西\ } 而 (0)

与使用基本块相比,以这种方式编写代码有哪些好处(如果有的话):

#define FOO \ { \ do_stuff_here \ 做更多的东西\ }

【问题讨论】:

标签: c macros multiline


【解决方案1】:

Andrey Tarasevich 提供以下解释:

  1. On Google Groups
  2. On bytes.com

[对格式进行了细微更改。在方括号中添加了括号注释[]]。

使用“do/while”版本的整个想法是制作一个宏,它将 扩展为常规语句,而不是复合语句。这是 这样做是为了使函数式宏的使用与 在所有上下文中使用普通函数。

考虑以下代码草图:

if (<condition>)
  foo(a);
else
  bar(a);

其中foobar 是普通函数。现在想象你会 喜欢用上述性质的宏[命名为CALL_FUNCS]替换函数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”的全部意义,并使 该宏几乎等同于复合语句版本。

我不知道为什么你在原文中引用的代码的作者 消息把这个;放在while (0)之后。在这种形式下,两种变体都是 相等的。使用“do/while”版本背后的整个想法不是 将这个最后的; 包含在宏中(出于我解释的原因 以上)。

【讨论】:

  • 原帖是我在comp.lang.c发的。 bytes.com 显然“挪用”了comp.lang.c 的内容,而没有提及任何来源。
猜你喜欢
  • 2012-05-30
  • 2013-10-07
  • 1970-01-01
  • 2021-04-14
  • 1970-01-01
  • 2012-11-25
  • 2010-10-29
相关资源
最近更新 更多