Trying to compile the following code on different compilers gives me two different results:
struct S{};
struct T{S S;};
int main(){}
As you can see, inside T
, I have an object named the same as the previously defined class S
.
On GCC 4.7.2, I get the following error pertaining to the S S;
declaration inside T
:
error: declaration of 'S T::S' [-fpermissive]
error: changes meaning of 'S' from 'struct S' [-fpermissive]
However, moving it outside of the class (or into main
) works fine:
struct S{};
S S;
int main(){}
What exactly does it mean by the error it's giving me?
In Visual Studio 2012, the whole thing compiles and runs without any errors. Pasting it into this Clang 3.0 compiler gives me no errors as well.
Which is right? Can I actually do this or not?
@JesseGood provide a complete answer, but if you really want to do this without any error, you can use type's full name and it will work as follow:
No there is no error, since
S
in your class isT::S
and its type is::S
!This code is ill-formed, no diagnostic required. Like the diagnostic says, if a declaration uses a name and the name has a different meaning than it would have when looked up at the end of the class definition, the programm is illformed, no diagnostic required.
gcc is correct, from [3.3.7 Class Scope]
However, note that
no diagnostic is required
, so all compilers are conforming.The reason is because of how class scope works. When you write
S S;
S
is visible within the entire class and changes the meaning when you useS
.