【问题标题】:Practical differences between "do {...} while (0)" and "{...} ((void)0)" in macros?宏中“do {...} while (0)”和“{...} ((void)0)”之间的实际区别?
【发布时间】:2015-04-30 21:47:54
【问题描述】:

C 中的常见做法是使用:

#define FOO() do { /* body */ } while (0)

虽然这很好,但也可以这样做:

#define FOO() { /* body */ }((void)0)

{...}((void)0) 具有许多相同的好处:您不会意外合并逻辑,并且在行尾需要 ;,所以像这样的奇怪表达式不会被忽视:@ 987654327@.

我注意到的唯一区别在于它意味着您需要在 if 语句中使用大括号。

if (a)
    FOO();
else
    BAR();

必须写成:

if (a) {
    FOO();
} else {
    BAR();
}

除了这个怪癖,它似乎运作良好,防止了do/while方法通常用于的相同类型的问题。

这两种方法有什么显着差异吗?

换一种说法,如果您看到使用{...}((void)0) 的代码库,除了已经指出的一个区别之外,是否还有实际的理由切换到使用do{..}while(0)

【问题讨论】:

  • { … } (void)0 变体从未在实践中使用过——我以前从未见过它建议过,甚至。这很简单奇怪!而且毫无意义。而且没用,因为您不能像 do { … } while (0) 替代品那样简单地使用它。 (void)0 演员表给你带来的正是任何有价值的东西——它没有任何好处。
  • 实际差异 #1:人们知道并识别 do { ... } while(0) 变体,而不是其他变体。
  • 你指出的差别很大。
  • @ideasman42:不,接下来的语法不需要分号。见rextester.com/KJLA9675
  • 同样的例子在 C:rextester.com/ADOSK79081

标签: c syntax macros


【解决方案1】:

实际差异正是您所指出的。

do { ... } while (0) 成语意味着宏可以在需要语句的任何上下文中使用。

您建议的习语{ ... } ((void)0) 可以安全地用于大多数需要表达式的上下文中——但如果在无括号的if 语句中使用它可能会失败。

当有一个众所周知的成语总是有效时,我想不出有什么好的理由使用一个几乎总是有效的陌生成语。

【讨论】:

  • 在一种情况下它不起作用 - 当您想在宏中使用 break 时,(虽然这不是经常做的事情)。
【解决方案2】:

一个不同之处是您可以将 break 与 #define FOO() do { /* body */ } while (0) 一起使用,但不能与 #define FOO() { /* body */ }(void)0 一起使用。

假设你在一个函数中,比如说hello(),并在#define FOO() do { /*some device operation */ } while (0) 中做某事,但发生了一些错误,所以你不想再继续使用该设备,但函数hello() 中有其他语句你想要执行,假设为另一台设备。

因此,如果您使用第二条语句,那么您很可能会 return 退出 hello(),但如果您使用第一条语句,您可以愉快地 break 并在同一函数 hello() 中为另一个设备执行一些操作.

【讨论】:

  • 我不相信这是一个引人注目的区别。您可以对正文进行编码,以便编写 if (!condition) { …rest of body… } 而不是 if (condition) break; …rest of body…。这是一个本质上微不足道的变化。您甚至可以在{ …here… } (void)0 版本中嵌入do ... while (0)
  • 发布一个例子:)
  • @JonathanLeffler 多个 if 条件怎么样?虽然你总是可以编码但可读吗?像这样ideone.com/wfC6Ib
  • 好的,如果它能让你信服,请查看此链接。但选择其中之一的原因之一是。它使事情的读写变得更加简单
  • 哪个链接?您实际上是在发布示例,还是我误解了您的评论的意思。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-02
  • 2013-10-07
  • 1970-01-01
  • 2021-04-14
  • 2016-01-08
  • 2014-10-09
相关资源
最近更新 更多