尝试在不同的编译器上编译以下代码给出了两个不同的结果:
struct S{};
struct T{S S;};
int main(){}
正如您所看到的,在T
内,我有一个与先前定义的类S
相同的对象。
在GCC 4.7.2上,I get the following error与S S;
内的T
声明相关:
错误:声明'S T :: S'[-fpermissive]
更改'S'的含义
错误:从'struct S'[-fpermissive]
但是,将其移到课堂之外(或main
)works fine:
struct S{};
S S;
int main(){}
它给我的错误究竟是什么意思?
在Visual Studio 2012中,整个程序编译并运行时没有任何错误。将其粘贴到this Clang 3.0 compiler中也没有错误。
哪个是对的?我真的可以这样做吗?
答案 0 :(得分:14)
gcc是正确的,来自[3.3.7 Class Scope]
类S中使用的名称N应引用其中的相同声明 上下文,并在完成范围内重新评估 违反此规则需要诊断。
但请注意no diagnostic is required
,因此所有编译器都符合要求。
原因是因为课程范围如何运作。撰写S S;
时S
在整个类中可见,并在您使用S
时更改含义。
struct S{};
struct T{
void foo()
{
S myS; // Not possible anymore because S refers to local S
}
S S;
};
答案 1 :(得分:6)
此代码格式错误,无需诊断。就像诊断所说的那样,如果一个声明使用了一个名称,并且该名称的含义与在类定义末尾查找时的含义不同,那么该程序就会生成错误,无需诊断。
答案 2 :(得分:6)
@JesseGood提供了一个完整的答案,但如果你真的想这样做而没有任何错误,你可以使用类型的全名,它将如下工作:
struct S {};
struct T { ::S S; };
int main() {return 0;}
没有错误,因为您班级中的S
为T::S
且其类型为::S
!