【问题标题】:Why does (void)0 stop "statement has no effect" warnings?为什么 (void)0 停止“声明无效”警告?
【发布时间】:2012-04-05 03:19:24
【问题描述】:

我有一个 trace() 宏,我用另一个宏打开和关闭,例如

#ifdef TRACE
    #define trace(x) trace_val(x, 0)
#else
    #define trace(x) 0
#endif

当我用未定义的TRACE 调用trace() 时,这会从gcc 生成warning: statement with no effect。经过一番搜索,我发现改变了

#define trace(x) 0

#define trace(x) (void)0

消除错误。我的问题是:为什么?有什么区别?

【问题讨论】:

  • @OrgnlDave 这个问题没有涉及为什么 (void)0 与 0 不同。
  • 我想它没有明确。如果你读到它,它会。删除我的评论为时已晚,但不要担心这不是结束问题的投票

标签: c macros


【解决方案1】:

强制转换为 void 表明程序员打算丢弃结果。警告的目的是表明该语句没有效果并不明显,因此提醒程序员注意这一点很有用,以防它是无意的。此处的警告毫无用处。

【讨论】:

  • 这有点道理。这是语言语法的记录部分吗?
  • 与其说是语言语法,不如说是特定的编译器。语言中没有规定警告,它们是编译器为了让事情变得更容易而做的额外措施。无论有没有编译器的警告,代码中的两种语法在语言级别都是有效的;它们的意思本质上是一样的,只是在一种情况下,它更“明显”(在非常非正式的意义上)是故意的。
  • 警告未在语言中规定。一些警告是,但这些警告是“这正式是一个错误,但我会让它溜走”。
【解决方案2】:

警告和解决方法是特定于编译器的。但是,您可以执行以下操作:

#define NOP do { } while(0)

#ifdef ENABLE_TRACE
    #define TRACE(x) trace_val(x, 0)
#else
    #define TRACE(x) NOP
#endif

这首先避免了潜在的问题。

【讨论】:

  • {} 是否会导致尾随分号出现问题? trace(x); trace(y); 最终会看起来像 {}; {};...
  • @cHao:这不是问题。这是if (foo) trace(x); else trace(y); {}; 将结束if 留下else 挂起。
  • 这将使x 未被使用,如果这是x 的唯一用途,则会导致警告。我喜欢:((void) (false && (x)))
  • @David:聪明。为什么是虚空演员?
  • 为了避免 OP 所询问的警告。 ;) false 避免评估 x,假设这是所需要的。 (您的解决方案也有效。事实上,我认为我更喜欢它。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多