21

对于以下代码:

struct foo {};

struct A
{
    typedef foo foo_type;

    void foo();
};

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 {};
        ^

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

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

4

1 回答 1

20

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

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

这是因为类范围是如何工作的。fooof在类的整个范围void foo();内都是可见的,因此声明的 typedef 中的含义从引用函数的名称发生了变化。Avoid foo();foostruct foofoo

于 2013-03-21T03:07:13.143 回答