在#undef之前我们什么时候需要#ifdef?

iam*_*ind 31 c c++ macros coding-style undef

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

#ifdef X
#undef X  // no statements in between
#endif
Run Code Online (Sandbox Code Playgroud)

我觉得,只需写下来就足够了:

#undef X
Run Code Online (Sandbox Code Playgroud)

如果X未定义宏,则#undef应该没有效果.

它是确定把独立的#undef,如果我想只取消定义宏?这是否会使编码练习变得糟糕?

Ken*_*oom 22

见ISO C99 6.10.3.5第2段.

表单的预处理指令

# undef identifier new-line
Run Code Online (Sandbox Code Playgroud)

导致指定的标识符不再被定义为宏名称.如果指定的标识符当前未定义为宏名称,则忽略它.

甚至Visual C++ 6(因标准不合规而臭名昭着)也允许这样:

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

  • 我可以确认这与[ISO C++ 11](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf)完全相同*. (8认同)

Mic*_*urr 11

我敢肯定这是历史的一件神器.正如jdigital的回答中提到的,第二版K&R说

将#undef应用于未知标识符并不是错误的.

然而,这句话不是1978年版.我很确定如果您尝试#undef使用未定义的宏,预标准编译器通常会抛出错误.

此外,ANSI C Rationale说:

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

我想如果它已经是普遍的做法,就没有必要在理由中说出来.

所有这一切,在现代代码中没有必要,但它也没有真正伤害.

  • 这是如何为强迫症:我设法谷歌了一个旧的DeSmet-C编译器为MS-DOS(从1984年的2.4版本!),它引发了一个错误,当我`#undef FOO` - `3#$$ undef FOO `/`错误:未定义` (8认同)
  • @MichaelBurr:请发表您的评论作为答案。我想为此给你一些代表。 (2认同)

jdi*_*tal 9

Kernighan和Ritchie(第2版)同意你的看法.

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

表格的控制线

# undef 识别码

导致标识符的预处理器定义被遗忘.如果没有错误地应用于#undef未知标识符.