我希望以下程序在GCC或Clang中发出诊断信息:
#undef protected
#undef private
由于[macro.names] / 2:
翻译单位不得以词法
#define
或#undef
命名 与关键字相同,与表3中列出的标识符相同,或与 7.6中描述了 attribute-tokens 。
protected
和private
都列在表3中。通过N3337进行“无需诊断”的快速查找并未显示任何内容。编译器在这种情况下需要投诉吗?
答案 0 :(得分:6)
[macro.names]是[reserved.names]的一部分,它声明"如果一个程序在保留它的上下文中声明或定义一个名称,那么除了明确允许的 这个条款,它的行为是不明确的。"所以它是未定义的行为。
实际上,大多数编译器都不会抱怨有两个原因:第一个是因为预处理通常在编译器评估符号是否是关键字之前进行;它是翻译的早期阶段。而且,如果您实际使用标准库,这些声明只是非法的(尽管其他库,如Posix或Windows,可能并且可能会施加类似的规则)。
编辑:
只是一般性评论:虽然没有全球声明
在标准中的作用,有一个一般的,基本的原则
违反库约束是未定义的行为;意图是
编译器不需要知道关于库的任何信息
一个实现可以完全像对待#include <vector>
#include "MyHeader.hpp"
(除了它寻找的地方
文件)。并且原始帖子中引用的限制是
对使用该库的程序的约束,仅适用于此类
程式。类似的东西:
#define while if
int
main( int argc, char** argv )
{
int retval = 0;
while ( argc > 0 ) {
++ retval;
-- argc;
}
return retval;
}
是一个完美定义合法的C ++(和C)程序,保证 返回1.(当然,我不推荐这样的东西。)
答案 1 :(得分:0)
是的,但实际上大部分都没有。 Clang最近收到了警告。
答案 2 :(得分:0)