[I believe that this is a regression.  Around 2.95.x or early 3.x, gcc produced
sensible error messages in similar circumstances.]

With the following code
-----------------------------------------
#include <map>

namespace NS {
struct Foo : public std::map<unsigned int, int>
{
};
}

using namespace NS;

bool foo (const Foo & m)
{
    return m.find (0x1234) != m.end;
}
----------------------------------------------------
the error message produced by gcc is unreadable nonsense:

temp.cc:13: error: no match for ‘operator!=’ in ‘((const
NS::Foo*)m)->NS::Foo::<anonymous>.std::map<_Key, _Tp, _Compare, _Alloc>::find
[with _Key = unsigned int, _Tp = int, _Compare = std::less<unsigned int>,
_Alloc = std::allocator<std::pair<const unsigned int, int> >](((const unsigned
int&)((const unsigned int*)(&4660u)))) != m->std::map<_Key, _Tp, _Compare,
_Alloc>::end [with _Key = unsigned int, _Tp = int, _Compare =
std::less<unsigned int>, _Alloc = std::allocator<std::pair<const unsigned int,
int> >]’

In detail:

(1)

> No match for '...

'operator!=' is in quotes.  When talking about a document, quote marks indicate
quotation.  But 'operator!=' is not a quotation from the document in question -
the source file.

(2)

> operator!=

'operator!=' is not the key for the look-up that failed.  The key was a triple
- the operator, and the types of each of the two arguments.  If the types were
given in the error message, there would be no need for the horrors that follow.

(3)

> in

'No match for A in B' means that 'A' does not occur within 'B'.  But in this
case the text after the word 'in' is not what we were looking up within; rather
it just gives more context to what is being looked up.  'from' would be a
better word than 'in'.

(4)

> '

more quote marks around text that is not a quote.

(5) The text within the second set of quote marks manages to expand 24
characters to several hundred.

That adds nothing to help the user understand the error; it hinders me, and I'm
more familiar with the language than many C++ programers, and have plenty of
general experience with decoding complex formal expressions.

Imagine someone being faced with this error message on their first attempt to
write a program.

(6)

> (const NS::Foo*)m

casting m to (const NS::Foo*) would indeed be worth an error message, but does
not occur in the original program.  It should not be in the error message.

(7)

> ->

The member reference was done with the correct '.' not the incorrect '->'.

(8)

> NS::Foo::

The member reference did not use a fully qualified name.

(9)

> <anonymous>

This is incorrect whatever it is meant to represent.  In particular, there are
no anonymous structs or namespaces involved in the member look-ups.

(10)

> .std::map<_Key, _Tp, _Compare, _Alloc>::find [with _Key = unsigned int, _Tp = 
> int, _Compare = std::less<unsigned int>, _Alloc = 
> std::allocator<std::pair<const unsigned int, int> >]

The find member was not given a fully qualified name.  The '.' is also
incorrect; an [incorrect] member access '->' has already been given.

(11)

> std::map<_Key, _Tp, _Compare, _Alloc>::find [with _Key = unsigned int, _Tp = 
> int, _Compare = std::less<unsigned int>, _Alloc = 
> std::allocator<std::pair<const unsigned int, int> >]

While separating out the template parameters will in some case avoid an
exponentially long type name, in this case it lengthens it and only confuses
the message.

Much better would be to state the type as std::map<unsigned int, int>, putting
the template parameters in the template instantiation, and dropping defaulted
template arguments.

(12)

> ((const unsigned int&)((const unsigned int*)(&4660u))

bears no relation to the integer constant expression actually used:

a. the original expression does not have a reference type.
b. the expression was given in hex, not decimal.
c. the address of the constant was not taken.  (You can't do that).
d. Nothing was cast to (const unsigned int*).
e. No pointer was cast to a reference, and that is not legal C++.

> m->

(13) should be '.' not '->'


-- 
           Summary: Error message for unmatched overload is gobbledygook
           Product: gcc
           Version: 4.0.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: suckfish at ihug dot co dot nz


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25362

Reply via email to