只要我不包含一个标题,重新定义C++关键字合法吗

Is it legal to redefine C++ keywords, as long as I do not include a single header?

本文关键字:定义 C++ 关键字 新定义 包含一 标题      更新时间:2023-10-16

考虑以下代码:

#define private public
struct Test {
private:
int s{9};
};
int main() { }

我已经经历了这个和这个。我这里没有包括一个标题。这是否意味着程序的行为已经被很好地定义,或者它仍然是根据C++标准定义的?

尽管它肯定会"起作用",而且你几乎可以保证不会调用"真正的"UB,但我认为,根据[lex]的冗长且有点模糊的阐述,从标准的字母来看,可以认为调用了Undefined Behavior。

类似地,做#define __included_foo_hstruct bar { int _Data; };这样的事情并没有"真正的伤害",但标准在[lex.name]中明确规定这些名称是保留的。不管你喜不喜欢,它就是这样。

不管它值多少钱,标准库总是使用__data__begin这样的名称,所以显然没有硬性的技术理由不这样做。只是。。。标准库是实现的一部分,您的程序没有这种自由。所以,是的,这可能根本不重要,但你仍然不被允许这样做(如果没有其他原因,只是担心你可能会以一种非常不明显、不可能调试的方式破坏标准库功能(。

特别是:

[lex.key]
表5中显示的标识符被保留用作关键字(也就是说,它们在第7阶段被无条件视为关键字(,属性令牌除外

[lex.phase]
7.分隔标记的空白字符不再重要。每个预处理令牌都被转换为一个令牌。由此产生的标记被语法和语义分析,并被翻译为一个翻译单元。

True,在第4阶段,会发生宏替换,因此第7阶段不会"看到"重新定义的关键字。尽管如此,它明确表示"保留"answers"无条件"。因此,如果允许您基于"但编译器看不到"忽略这一点,那么您也可以使用相同的逻辑,例如#define __inline inline [[gnu:always_inline]]。谁在乎是否保留了双下划线,编译器看不到!

我不认为,尽管它肯定会"奏效",但这是一个严格合法的观点。

(有趣的事实:我自己也用过#define private public一次,效果很好。(