定义成员函数时编译错误,但仅在GCC中编译

Sup*_*mum 13 c++ gcc using-declaration language-lawyer

以下程序与MSVS,clang和GCC编译时没有错误:

class A;

namespace Y {
    using ::A;
    class A {};
}

int main() {}
Run Code Online (Sandbox Code Playgroud)

现在让我们定义一个成员函数.现在它仍然可以编译MSVS和clang,但不能与GCC编译:

class A;

namespace Y {
    using ::A;
    class A { void f() {} };
}

int main() {}
Run Code Online (Sandbox Code Playgroud)

GCC给出以下错误消息:

  • prog.cc:5:22:错误:'void A :: f()'的定义不在包含'A'[-fpermissive]的命名空间中

这是为什么?这是GCC中的错误吗?

如果该程序的第二个版本违反了c ++标准的规则,它违反了什么规则,为什么MSVS和clang没有为该违规提供诊断消息?

这是c ++标准含糊不清的情况吗?

从错误消息看起来GCC错误地认为我们违反了以下规则:

我们没有违反此规则,因为成员函数定义在类定义中.我的理论是,海湾合作委员会混淆了宣言类A; 在全局命名空间中,在命名空间Y中有类定义类A {...}.我认为我们在GCC中有一个错误.

通过海湾合作委员会,他们宣布同一实体.通过观察在程序的第一个版本中可以看出,在使用GCC进行编译时,可以使用:: A作为main中的完整类型.MSVS也是如此.然而,对于Clang,他们宣布了不同的实体.这种差异可能是因为c ++标准的模糊性.无论这种模棱两可,我们显然都没有违反http://eel.is/c++draft/class.mfct#2.这个规则很清楚.

相关问题:与GCC中使用声明编译相同范围内的类声明,但不是MSVS

Sup*_*mum 5

根据c ++标准,这两个程序的格式都不正确。这是由于与相关问题相同的原因:

与在GCC中使用声明编译相同的作用域中的类声明,但在MSVS中没有

在这两种情况下,所有编译器都应给出编译错误:因此,这表明MSVS,clang和GCC中存在错误。

clang中的错误已得到确认并已修复:https ://llvm.org/bugs/show_bug.cgi?id =24030

GCC为第二个程序给出奇怪的错误消息的原因是,当GCC无法检测到第一个程序和第二个程序中都存在的错误时,就会感到困惑。