The test-case: // testcase: ------------------------- struct A { struct B { }; }; struct C : A, A::B { void foo(B b); void bar(B* pb); }; //------------------------------------ ============== The error: foo.cc:11: error: reference to 'B' is ambiguous foo.cc:5: error: candidates are: struct A::B foo.cc:5: error: struct A::B foo.cc:11: error: 'B' has not been declared foo.cc:12: error: reference to 'B' is ambiguous foo.cc:5: error: candidates are: struct A::B foo.cc:5: error: struct A::B foo.cc:12: error: 'B' has not been declared ------------- There is only one type "B", whether it's referred to as ::A::B, (from the global scope), or "A::B", injected from the first inheritance, or simpy "B" injected from the second. These all refer to the same type. There is no ambiguity. Note, GCC accepts this if the "foo" member functions are delcared w/ namespace qualification. For example, this code is accepted: struct C : A, A::B { void foo(A::B b); void bar(A::B* pb); }; ================= This behaviour is found in the following versions of GCC: egcs-2.91.66, gcc-3.2, gcc-3.3, gcc-3.4.3, gcc-3.4.6, gcc-4.0 I haven't tried other versions.
Confirmed. To make things worse, the diagnostic is really longish right now as well: g/x> c++ -c x.cc x.cc:10: error: reference to 'B' is ambiguous x.cc:4: error: candidates are: struct A::B x.cc:4: error: struct A::B x.cc:10: error: reference to 'B' is ambiguous x.cc:4: error: candidates are: struct A::B x.cc:4: error: struct A::B x.cc:10: error: 'B' has not been declared x.cc:11: error: reference to 'B' is ambiguous x.cc:4: error: candidates are: struct A::B x.cc:4: error: struct A::B x.cc:11: error: reference to 'B' is ambiguous x.cc:4: error: candidates are: struct A::B x.cc:4: error: struct A::B x.cc:11: error: 'B' has not been declared The 'is ambiguous' message is apparently printed twice, and the 'has not been declared' message is, and has long been, bogus... W.
I just confirmed this bug in GCC 4.3.0.
Bug still in version 4.3.4: $ g++ -c bug27775.cc bug27775.cc:11: error: reference to 'B' is ambiguous bug27775.cc:5: error: candidates are: struct A::B bug27775.cc:5: error: struct A::B bug27775.cc:11: error: reference to 'B' is ambiguous bug27775.cc:5: error: candidates are: struct A::B bug27775.cc:5: error: struct A::B bug27775.cc:11: error: 'B' has not been declared bug27775.cc:12: error: reference to 'B' is ambiguous bug27775.cc:5: error: candidates are: struct A::B bug27775.cc:5: error: struct A::B bug27775.cc:12: error: reference to 'B' is ambiguous bug27775.cc:5: error: candidates are: struct A::B bug27775.cc:5: error: struct A::B bug27775.cc:12: error: 'B' has not been declared $ g++ -dumpversion 4.3.4 Also in version 4.4.4: $ g++ -c bug27775.cc bug27775.cc:11: error: reference to 'B' is ambiguous bug27775.cc:5: error: candidates are: struct A::B bug27775.cc:5: error: struct A::B bug27775.cc:11: error: reference to 'B' is ambiguous bug27775.cc:5: error: candidates are: struct A::B bug27775.cc:5: error: struct A::B bug27775.cc:11: error: 'B' has not been declared bug27775.cc:12: error: reference to 'B' is ambiguous bug27775.cc:5: error: candidates are: struct A::B bug27775.cc:5: error: struct A::B bug27775.cc:12: error: reference to 'B' is ambiguous bug27775.cc:5: error: candidates are: struct A::B bug27775.cc:5: error: struct A::B bug27775.cc:12: error: 'B' has not been declared $ g++ -dumpversion 4.4.4 $ Also in 4.5.1: $ g++ -c bug27775.cc bug27775.cc:11:14: error: reference to 'B' is ambiguous bug27775.cc:5:5: error: candidates are: struct A::B A::B::B bug27775.cc:5:5: error: struct A::B bug27775.cc:11:14: error: 'B' has not been declared bug27775.cc:12:14: error: reference to 'B' is ambiguous bug27775.cc:5:5: error: candidates are: struct A::B A::B::B bug27775.cc:5:5: error: struct A::B bug27775.cc:12:14: error: 'B' has not been declared $ g++ -dumpversion 4.5.1
Also confirmed with GCC 4.7 rev 180166. Clang 3.0 also reject this, so I am not sure whether is actually valid, but the repeated messages are suspicious. /tmp/webcompile/_9463_0.cc:10:14: error: member 'B' found in multiple base classes of different types void foo(B b); ^ /tmp/webcompile/_9463_0.cc:3:12: note: member found by ambiguous name lookup struct B ^ /tmp/webcompile/_9463_0.cc:3:12: note: member found by ambiguous name lookup /tmp/webcompile/_9463_0.cc:11:14: error: member 'B' found in multiple base classes of different types void bar(B* pb); ^ /tmp/webcompile/_9463_0.cc:3:12: note: member found by ambiguous name lookup struct B ^ /tmp/webcompile/_9463_0.cc:3:12: note: member found by ambiguous name lookup 2 errors generated.
(In reply to Manuel López-Ibáñez from comment #4) > Clang 3.0 also reject this, so I am not sure whether is actually valid, but > the repeated messages are suspicious. > EDG accepts it, and I can see nothing wrong with the code according to the standards. The following versions of GCC also reject it with substantially similar error messages: 10.1.0 11.1.0 5.4.0 6.3.0 7.1.0 7.4.0 8.1.0 8.3.0 9.1.0 9.2.0