#undef关键字是非法的吗?

时间:2014-12-09 11:06:14

标签: c++

我希望以下程序在GCC或Clang中发出诊断信息:

#undef protected
#undef private

由于[macro.names] / 2:

  

翻译单位不得以词法#define#undef命名   与关键字相同,与表3中列出的标识符相同,或与   7.6中描述了 attribute-tokens

protectedprivate都列在表3中。通过N3337进行“无需诊断”的快速查找并未显示任何内容。编译器在这种情况下需要投诉吗?

3 个答案:

答案 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)

使用为关键字保留的名称肯定不是一个好主意。但是,大多数编译器都不会就此发出警告。

您可以查看Keywords redefinition in C / C++

它在类似的路线上。