Created attachment 44784 [details] test code Hello. The following c++ code compiles with 'clang++ -std=c++17 test.cpp' but not with 'g++ -std=c++17 test.cpp' I don't know who's right between clang and gcc, but I suspect that gcc reads the 'typedef t t' line backward, and therefore override the first 't' with the second one. This bug might be related to bug number 23594 Best regards --- test.cpp --- namespace test{ typedef double t; struct A{ typedef t t; }; } int main(int,char**){return 0;} --- g++ error message --- g++ -std=c++17 test.cpp test.cpp:5:16: error: declaration of ‘typedef test::t test::A::t’ [-fpermissive] typedef t t; ^ test.cpp:2:19: error: changes meaning of ‘t’ from ‘typedef double test::t’ [-fpermissive] typedef double t; --- g++ --version --- g++ (GCC) 8.1.1 20180712 (Red Hat 8.1.1-5)
The standard says: A name N used in a class S shall refer to the same declaration in its context and when re-evaluated in the completed scope of S. No diagnostic is required for a violation of this rule. Before the typedef the name 't' refers to the declaration of test::t, but after the typedef the name 't' refers to the declaration of A::t. Even though the two declarations denote the same type, they are distinct declarations, which violates the rule. Clang is less strict and does not diagnose the violation of the rule. Arguably a special case could be given to allow it when the two declarations refer to the same entity, but since the typedef seems completely pointless anyway I don't see any benefit to adding a special case.
P.S. it has nothing to do with namespaces: typedef double t; struct A{ typedef t t; }; int main() { }
Also see [dcl.typedef] paragraphs 3 and 4 in the standard, which has an example very similar to this: struct S { typedef struct A { } A; // OK typedef struct B B; // OK typedef A A; // error };