定义成员函数时编译错误,但仅在 GCC 中
Compile error when defining a member function, but only in GCC
以下程序使用 MSVS、clang 和 GCC 编译时没有错误:
class A;
namespace Y {
using ::A;
class A {};
}
int main() {}
现在让我们定义一个成员函数。现在它仍然可以用 MSVS 和 clang 编译,但不能用 GCC 编译:
class A;
namespace Y {
using ::A;
class A { void f() {} };
}
int main() {}
GCC 给出以下错误信息:
- prog.cc:5:22:错误:'void A::f()' 的定义不在包含 'A' [-fpermissive]
的命名空间中
这是为什么?这是 GCC 中的错误吗?
如果程序的第二个版本违反了 c++ 标准的规则,它违反了什么规则,为什么 MSVS 和 clang 没有针对该违反给出诊断消息?
这是否是 c++ 标准含糊不清的情况?
从错误消息来看,GCC 似乎错误地认为我们违反了以下规则:
- http://eel.is/c++draft/class.mfct#2 "A member function definition that appears outside of the class definition shall appear in a namespace scope enclosing the class definition."
我们没有违反这个规则,因为成员函数定义在 class 定义中。我的理论是 GCC 混淆了声明 class A;在具有 class 定义的全局命名空间中 class A { ... } 在命名空间 Y 中。我认为我们在 GCC 中有一个错误。
对于 GCC,它们声明相同的实体。这可以通过观察在程序的第一个版本中使用 GCC 编译时可以在 main 中使用 ::A 作为完整类型来看出。 MSVS 也一样。然而,对于 Clang,它们声明了不同的实体。这种差异可能是因为 c++ 标准中的歧义。不管这样的歧义,我们显然没有违反 http://eel.is/c++draft/class.mfct#2 。那个规则很清楚。
相关问题:
根据 c++ 标准,这两个程序都是病式的。这是因为与相关问题相同的原因:
所有编译器在这两种情况下都应该给出编译错误:所以这表明 MSVS、clang 和 GCC 中存在错误。
clang中的bug已经确认并修复:https://llvm.org/bugs/show_bug.cgi?id=24030
GCC 为第二个程序给出奇怪错误消息的原因是,当它未能检测到第一个和第二个程序中都存在的错误时,它会感到困惑。
以下程序使用 MSVS、clang 和 GCC 编译时没有错误:
class A;
namespace Y {
using ::A;
class A {};
}
int main() {}
现在让我们定义一个成员函数。现在它仍然可以用 MSVS 和 clang 编译,但不能用 GCC 编译:
class A;
namespace Y {
using ::A;
class A { void f() {} };
}
int main() {}
GCC 给出以下错误信息:
- prog.cc:5:22:错误:'void A::f()' 的定义不在包含 'A' [-fpermissive] 的命名空间中
这是为什么?这是 GCC 中的错误吗?
如果程序的第二个版本违反了 c++ 标准的规则,它违反了什么规则,为什么 MSVS 和 clang 没有针对该违反给出诊断消息?
这是否是 c++ 标准含糊不清的情况?
从错误消息来看,GCC 似乎错误地认为我们违反了以下规则:
- http://eel.is/c++draft/class.mfct#2 "A member function definition that appears outside of the class definition shall appear in a namespace scope enclosing the class definition."
我们没有违反这个规则,因为成员函数定义在 class 定义中。我的理论是 GCC 混淆了声明 class A;在具有 class 定义的全局命名空间中 class A { ... } 在命名空间 Y 中。我认为我们在 GCC 中有一个错误。
对于 GCC,它们声明相同的实体。这可以通过观察在程序的第一个版本中使用 GCC 编译时可以在 main 中使用 ::A 作为完整类型来看出。 MSVS 也一样。然而,对于 Clang,它们声明了不同的实体。这种差异可能是因为 c++ 标准中的歧义。不管这样的歧义,我们显然没有违反 http://eel.is/c++draft/class.mfct#2 。那个规则很清楚。
相关问题:
根据 c++ 标准,这两个程序都是病式的。这是因为与相关问题相同的原因:
所有编译器在这两种情况下都应该给出编译错误:所以这表明 MSVS、clang 和 GCC 中存在错误。
clang中的bug已经确认并修复:https://llvm.org/bugs/show_bug.cgi?id=24030
GCC 为第二个程序给出奇怪错误消息的原因是,当它未能检测到第一个和第二个程序中都存在的错误时,它会感到困惑。