[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 '->'
*** Bug 25363 has been marked as a duplicate of this bug. ***
Without going into details with the different points, I agree that the dump of the tree is unreadable and not helpful. I know Gaby disagrees, but I take the liberty to confirm this report. W.
There has not been any movement on this bug in over a year. Could someone explain to me the reason for the cryptic error message. Why can't gcc just report something like: no match for operator!=(<type>, <type>)
(In reply to comment #3) > There has not been any movement on this bug in over a year. > > Could someone explain to me the reason for the cryptic error message. > Why can't gcc just report something like: > > no match for operator!=(<type>, <type> Indeed! I am totally convinced that %qE must die! See also PR50817 and there are few others.
Duplicated. The other bug has a better discussion. *** This bug has been marked as a duplicate of bug 49152 ***