【问题标题】:When do we need #ifdef before #undef?我们什么时候需要在#undef 之前使用#ifdef?
【发布时间】:2012-02-23 19:42:21
【问题描述】:

在许多 C 和 C++ 文件中,我都看到过这样的宏:

#ifdef X
#undef X  // no statements in between
#endif

我觉得,简单写就够了:

#undef X

如果未定义宏 X,则 #undef 应该无效。

如果我只想取消定义一个宏,是否可以ok放置独立的#undef?无论如何,这会使编码实践变得糟糕吗?

【问题讨论】:

  • 我同意;我只是快速搜索了一下,这种行为似乎在主要编译器中是一致的。也许有些历史上不允许您取消定义未定义的宏?不确定。我会说它可能是安全的。
  • 在我看来,它本身就很好
  • 我想我记得至少 MSVC 对我犯了错误。
  • @Xeo,也许在过去。 MSDN 认为从 VS2005 开始就可以了。
  • @anthony:文档实际上说它早在 VS 2003 就有效。他考虑的可能是 VC 6,因其缺乏标准合规性而臭名昭著。

标签: c++ c coding-style macros undef


【解决方案1】:

参见 ISO C99 6.10.3.5 第 2 段。

表单的预处理指令

# undef identifier new-line

导致指定的标识符不再被定义为宏名称。如果 指定的标识符当前未定义为宏名称。

即使Visual C++ 6(因不符合标准而臭名昭著)也允许这样做:

您还可以将#undef 指令应用于之前没有定义的标识符。这确保了标识符是未定义的。宏替换不在#undef 语句中执行。

【讨论】:

【解决方案2】:

我确信这是历史的产物。 As mentioned in jdigital's answer,K&R第二版说

将#undef 应用于未知标识符并没有错。

但是,1978 年版中没有这句话。如果您尝试 #undef 未定义的宏,我很确定预标准编译器通常会抛出错误。

另外,ANSI C Rationale says:

明确允许#undef 没有当前定义的宏。

我想如果这已经是普遍的做法,就没有必要在理由中指出它了。

综上所述,在现代代码中这不是必需的,但也没有什么坏处。

【讨论】:

  • 我没有证据,但我敢打赌那个时代的 C 编译器(第一版)不会抛出错误。它不符合 Unix 哲学。
  • 这对强迫症有什么影响:我设法用谷歌搜索了一个用于 MS-DOS 的旧 DeSmet-C 编译器(1984 年的 2.4 版!),当我 #undef FOO -- @ 时它抛出一个错误987654325@/error:not defined
  • 你赢了! (MS-DOS 的人显然没有理解 Unix 哲学。)
  • @MichaelBurr:请发表您的评论作为答案。我想给你一些代表。
【解决方案3】:

Kernighan 和 Ritchie(第 2 版)同意您的观点。

编辑:引用来源(A12.3 节):

表单的控制线

# undef标识符

导致忘记标识符的预处理器定义。如果将#undef 应用于未知标识符是正确的。

【讨论】:

  • 能否引用出处?
  • @anthony-arnold:根据要求引用来源。
猜你喜欢
  • 1970-01-01
  • 2019-07-17
  • 2021-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多