C ++预处理器#定义一个关键字。 它符合标准吗?

帮助解决关于布尔和1的这个问题的评论正在进行的辩论:

符合标准的C ++预处理器是否允许使用#define重新定义语言关键字? 如果是这样,一个符合标准的C ++预处理器是否允许这样做?

如果一个C ++程序重新定义了一个语言关键字,那么这个程序本身是否符合标准呢?

在C ++中,禁止#define一个关键字最接近的是§17.4.3.1.1/ 2,它只允许在包含标准库头的翻译单元中使用它:

包含标题的翻译单元不得包含任何定义该标题中声明或定义的名称的macros。 这样的翻译单位也不应该定义与关键字词汇相同的名称的macros。

该段的第二个句子已经在C ++ 0x中更改为彻底禁止#define一个关键字(C ++ 0x FCD§17.6.3.3.1):

翻译单位不得#define或#undef与关键字词汇相同的名称。

编辑:正如Ken Bloom在他的回答中所指出的,规则在C ++ 0x中没有改变; 这个文本刚刚被重新整理,把像我这样的人混淆了。 🙂

从2005-10-19 C ++工作草案开始工作 (因为我没有标准的方便):

16.3节将#define的语法定义为#define #define identifier replacement-list-newline (类似于对象的macros),或者以#define identifier lparen (类似于函数的macros)开头的几个结构之一。 identifier在第2.10节定义identifier-nondigit | identifier identifier-nondigit | identifier digit identifier-nondigit | identifier identifier-nondigit | identifier digit identifier-nondigit | identifier identifier-nondigit | identifier digit 。 2.11节指出,在编译的第7阶段(第2.1节),某个标识符列表被无条件地视为关键字,因此我得出结论,因此在第4阶段(预处理器扩展)中并没有专门对待它们。 因此,标准似乎要求预处理器允许您重新定义语言关键字(在2.11节中列出)

但是,预处理器有一个自己的关键字,即已defined的关键字,以及一个预定义的macros列表(见第16.8节)。 如果您重新定义这些行为,则第16.8节指出行为未定义,但不禁止预处理器将其识别为macros名称。