The actual problem is a missing "typename" on the reported line, but you'd never figure that out from the message.
Created attachment 6176 [details] Source code
Created attachment 6177 [details] Compiler output (-v -save-temps)
Fixed for 3.4.0 which is out: In file included from testPowerset.cc:5: /home/ivan/ootbc/common/include/powerset.hh:112: error: type `Powerset<E>' is not derived from type `Powerset<E>::iterator' /home/ivan/ootbc/common/include/powerset.hh:112: error: ISO C++ forbids declaration of `difference_type' with no type /home/ivan/ootbc/common/include/powerset.hh:112: error: expected `;' before "difference_type"
The "fixed" note just repeats the same error message I'm complaining about on 3.3. How about a message "Use of type from enclosing template class requires 'typename'" or similar? What in the compiler is thinking that "Powerset<E>" needs to be derived from `Powerset<E>::iterator', anyway? There are no base classes or derivations here - I call it confusing and probably indicating a lost compiler. Ivan
/home/ivan/ootbc/common/include/powerset.hh:112: error: type `Powerset<E>' is not derived from type `Powerset<E>::iterator' The error message is correct.
Come on! The error message is certainly *true*, but *correct* means that it diagnoses the actual error that is present and helps the user toward a correction. This message certainly does neither. The actual error is a missing "typename". Taken at face value, the message suggests that 'Powerset<E> should be derived from its local type "Powerset<E>::iterator", but it is impossible for a class to derive from one of its own local types. You may argue that the problem is low priority, but "correct" it ain't. Take it up with your associates.
Confirmed after looking at the code again I think this is valid as iterator is an inner class and Type is just the outter class, reduced testcase: template<class E> class Powerset { typedef Powerset<E> Type; typedef int difference_type; class iterator { typedef Type::difference_type difference_type; }; };
Lets keep this for the error message, because PR 9634 is the bug which talks about this being not a bug but the standard is not clear.
Confirmed. For this code ----------- template <class T> class O { typedef O<T> Type; typedef int inner; class I { typedef Type::inner inner; }; }; ----------- gcc produces g/x> /home/bangerth/bin/gcc-3.5-pre/bin/c++ -c x.cc x.cc:6: error: type `O<T>' is not derived from type `O<T>::I' x.cc:6: error: ISO C++ forbids declaration of `inner' with no type x.cc:6: error: expected `;' before "inner" which is indeed confusing. (icc, for reference, simply accepts the code even with -Xc -ansi -- which is probably wrong.) Frankly, I have no clue what path in the compiler we are taking to get to this error message... W.
It doesn't need to involve nested classes either: ----------------------------- template <bool> struct A { typedef int type; }; template <bool yn> struct B { typedef A<yn>::type Type; }; ----------------------------- 3.4 and mainline give: bug.cc:8: error: type `A<<anonymous> >' is not derived from type `B<yn>' bug.cc:8: error: ISO C++ forbids declaration of `type' with no type bug.cc:8: error: expected `;' before "Type" Again, the problem is a missing "typename" but you can't guess that from the diagnostic. Compiling the same code with GCC 3.3 gives the "implicit typename is deprecated" warning which makes the error much easier to find, therefore I consider this a regression against 3.3
*** Bug 28182 has been marked as a duplicate of this bug. ***
*** Bug 30754 has been marked as a duplicate of this bug. ***
Let's give meaningful short descriptions to the bugs, please.
Created attachment 16681 [details] Another C++ example to ilustrate misleading error message about missing typename keyword This is a short example where one is getting completely misleeding error message: test.cpp:22: error: expected constructor, destructor, or type conversion before ‘&’ token I had to try to compile this example with Visual C++ to figured out what's the reason of compiler error was. It reported it more clearly. Tried: GNU C++ (GCC) version 4.3.0 20080428 (Red Hat 4.3.0-8) (x86_64-redhat-linux) GNU C++ version 3.4.6 20060404 (Red Hat 3.4.6-9) (x86_64-redhat-linux)
Testcase in comment #9 does not produce any output anymore. Testcase in comment #10 produces: /home/manuel/src/pr15179.C:8:18: error: type ‘A<yn>’ is not derived from type ‘B<yn>’ /home/manuel/src/pr15179.C:8:23: error: expected ‘;’ before ‘Type’ Testcase in comment #14 produces: /home/manuel/src/pr15179-3.C: At global scope: /home/manuel/src/pr15179-3.C:22:23: error: expected constructor, destructor, or type conversion before ‘&’ token It seems to me that there is a tentative parse of a type in cp_parser_decl_specifier_seq, that fails, and then we end up trying to parse something else until it fails completely. For the typedef testcases, the code in cp_parser_decl_specifier_seq could just directly parse the complete typedef and return, because only a type can follow typedef. For the non-typedef testcase, it is less clear how to handle a failure to parse a type, since that may actually mean we are looking at something else. I don't really know where the "failure" happens. That would need more debugging that I have time to do now. Any help appreciated.
*** This bug has been marked as a duplicate of 15946 ***