考虑以下代码:
#define private public
struct Test {
private:
int s{9};
};
int main() { }
我已经经历过this和this。我没有在此处包含单个标头。这是否意味着该程序的行为已被良好定义,还是仍根据C ++标准进行了定义?
尽管它肯定会“起作用”,并且可以保证您不会调用“真正的” UB,但我认为标准的文字可能会认为未定义行为是根据{{1}}冗长而含糊的说明被调用。
类似地,执行[lex]
或#define __included_foo_h
之类的操作并没有“真正的伤害”,但是该标准在struct bar { int _Data; };
中明确指出这些名称是保留的。不管喜欢与否,这就是事实。
无论价值多少,标准库始终使用[lex.name]
或__data
之类的名称,因此显然没有严格的技术理由不这样做。仅...标准库是实现的一部分,而您的程序没有这种自由。因此,是的,这可能根本不重要,但是您仍然不被允许这样做(如果出于其他原因,除了担心您可能会以一种非常明显的,无法调试的方式破坏标准库功能)方式)。
尤其是:
[lex.key]
外,表5中显示的标识符被保留用作关键字(即在阶段7中被无条件视为关键字)。
除属性令牌[lex.phases]
7.分隔标记的空格字符不再重要。每个预处理令牌都将转换为令牌。对生成的令牌进行语法和语义分析,并将其作为翻译单元进行翻译。
确实,在阶段4中,发生宏替换,因此阶段7不会像这样“看到”重新定义的关键字。尽管如此,它仍然清楚地表明“保留”和“无条件”。因此,如果只允许您基于“但编译器看不到它”而忽略它,那么您也可以例如__begin
具有相同的逻辑。谁在乎是否保留双下划线,编译器看不到!
我不认为,尽管它肯定会“起作用”,但这是严格合法的观点。
(有趣的事实:我曾经用过#define __inline inline [[gnu:always_inline]]
,就像一个咒语一样。)