3

我可以在 C 中使用#define 重新定义关键字吗?

我在 C++ 标准中发现了这一点:

ISO/IEC 14882:1998 和 ISO/IEC 14882:2003

17.4.3.1.1 宏名称 [lib.macro.names]

2 包含头文件的翻译单元不应包含定义在该头文件中声明或定义的名称的任何宏。这样的翻译单元也不应为在词法上与关键字相同的名称定义宏。

164) 不允许使用#undef 指令删除库宏定义。

ISO/IEC 14882:2011

17.6.4.3.1 宏名称 [macro.names]

2 翻译单元的#define 或#undef 名称不得与关键字、表 3 中列出的标识符或 7.6 中描述的属性标记在词汇上相同。

所以,如果我们包含标准 C++ 库中的任何头文件,我们就不能在 C++98 / C++03 中重新定义关键字,而在 C++11 中,我们不能在任何翻译单元中这样做,对吧?

4

3 回答 3

3

你能?是的,大多数编译器不会强行阻止它。

你应该?不,(几乎)从不,这(通常)是一个可怕的想法。各种各样的事情都可能发生故障,并且与大多数预处理器废话一样,调试起来将非常困难。

所以,你能合法吗?不。

以同样的方式,您可以拥有以命名空间或各种其他非常糟糕的事物开头__或添加事物的宏或变量。std::然而,像这样的大多数规则都有很好的理由(主要是与关键字或名称解析相关的冲突)。虽然这在物理上可能是可行的,但您需要的时间很少(如果有的话),而且应该的时间也更少。

于 2012-09-05T17:27:40.087 回答
2

在 C 标准中,这是不允许的。

C11, § 6.4.1 关键词

[...]

上述标记(区分大小写)保留(在翻译阶段 7 和 8 中)用作关键字,否则不得使用。

于 2012-09-05T17:28:38.190 回答
1

这个问题有几个方面:

  • 如果您要重新定义关键字,那么在 95% 的编译器中,无论标准中写了什么,这都能正常工作,主要是因为这在旧编译器中工作;
  • 您永远无法确定这将在您的编译器的下一个版本中起作用;
  • 从实际的角度来看,您应该避免这种情况。代码将更难阅读和理解。

底线:你真的需要这个吗?你会得到什么?

ps 我见过几次try-catch在各种标题中重新定义。

于 2012-09-05T17:30:39.403 回答