gcc-bug: gcc reports error in valid code (STL-related)

Martin v. Loewis martin@loewis.home.cs.tu-berlin.de
Fri Dec 31 20:54:00 GMT 1999


> Although STL-errors are a well-known thing, I believe this one is
> actually a compiler error.

Hi Axel,

Thanks for your bug report. This is neither-nor - it is a bug in your
code.

> To make sure the code is realy valid, I checked back with
> copm.lang.c++.moderated.

Can you please point me to the thread on Dejanews?

> template <class T> class A : protected list<T*>
> {
[...]
>     void f (double p)
>     {
>       iterator i = begin();  // o.k.
>       reverse_iterator j = rbegin();  // test.cpp:12: parse error before `='
>       list<T*>::reverse_iterator k = rbegin();  // o.k.
>     }
> };

The problem is that the base class of a template is not searched
during name lookup, if the base depends on a template parameter
(14.6.2/3). Therefore, both iterator and reverse_iterator do not refer
to list<T*>::iterator and list<T*>::reverse_iterator (respectively);
only the third line uses the correct type.

Instead, lookup of reverse_iterator finds the global

template <class _Iterator>
class reverse_iterator;

This is a parse error, because template parameters are expected in
this context.

Now, why does it accept iterator? This is an extension: If g++ does
not find a global name, instead of giving an error, it does consider
the base templates. With -pedantic, the first line also is in error
(since iterator is not found as a type).

Also, the third line is in error with -pedantic. Since
list<T*>::iterator is a dependent name, it is considered as an object
during syntax analysis, and not as a type-name. To make it a typename,
the correct usage would be:

  typename list<T*>::reverse_iterator k = rbegin();  // o.k.

Since these rules are rarely enforced by the compiler, and since no
compiler gets it right all the time (*), people often are unaware of
the rules.

Mit besten Grüßen,
Martin

(*) In gcc, the base is only not searched for type names. Member
fields of the base type are found during instantiation. The bug here
is that independent names should be looked up at point of declaration,
not at the point of instantiation.



More information about the Gcc-bugs mailing list