方法声明改变了符号的含义

HC4*_*ica 18 c++ token-name-resolution

对于以下代码:

struct foo {};

struct A
{
    typedef foo foo_type;

    void foo();
};
Run Code Online (Sandbox Code Playgroud)

GCC给出了一个编译器错误:

test.cpp:7:14: error: declaration of 'void A::foo()' [-fpermissive]
     void foo();
              ^
test.cpp:1:8: error: changes meaning of 'foo' from 'struct foo' [-fpermissive]
 struct foo {};
        ^
Run Code Online (Sandbox Code Playgroud)

但clang接受它没有编译器错误.谁是对的?

请注意,如果删除typedef或将其更改为typedef ::foo foo_type,则gcc和clang都接受该代码.

Jes*_*ood 18

gcc是正确的,但clang不需要提供诊断(3.3.7):

在类S中使用的名称N应在其上下文中引用相同的声明,并在完成的S范围内重新评估.违反此规则不需要诊断.

这是因为类范围的工作原理.该foovoid foo();是内可见整个类的范围A,这样的声明void foo();改变的意义foo,从指的typedef struct foo的函数的名称foo.