C多行宏:do/while(0) vs scope block [重复]

Posted

技术标签:

【中文标题】C多行宏:do/while(0) vs scope block [重复]【英文标题】:C multi-line macro: do/while(0) vs scope block [duplicate] 【发布时间】: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 \ 做更多的东西\

【问题讨论】:

重复:***.com/questions/923822 和 ***.com/questions/154136 和 ***.com/questions/257418 实际上还有另一种方法可以让事情变得正确。 (...) 可以做与 while(0) 相同的事情。参考:bruceblinn.com/linuxinfo/DoWhile.html @wuxb:(...) 构造是 GCC 扩展,不受 ISO 标准 C 支持。 这也是 CERT 推荐的方法:wiki.sei.cmu.edu/confluence/display/c/… 【参考方案1】:

Andrey Tarasevich 提供以下解释:

    On Google Groups 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 的内容,而没有提及任何来源。

以上是关于C多行宏:do/while(0) vs scope block [重复]的主要内容,如果未能解决你的问题,请参考以下文章

C语言do...while语句的妙用(包裹宏替换多句代码)(代替go to语法)(隔绝外部变量)

在 C 宏中,是不是应该更喜欢 do ... while(0,0) 而不是 do ... while(0)?

嵌入式宏定义中do...while的意义

C语言陷阱与技巧第7节,define函数式宏定义不能用普通函数代替吗?为什么要使用do{}while包裹代码

do while的作用

do while的作用