Bug 25362 - pretty printing of expression fails
Summary: pretty printing of expression fails
Status: RESOLVED DUPLICATE of bug 49152
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.0.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
: 25363 (view as bug list)
Depends on:
Blocks:
 
Reported: 2005-12-12 09:32 UTC by Ralph Loader
Modified: 2012-03-21 13:21 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2006-03-08 05:11:08


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ralph Loader 2005-12-12 09:32:06 UTC
[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 '->'
Comment 1 Andrew Pinski 2005-12-12 19:33:18 UTC
*** Bug 25363 has been marked as a duplicate of this bug. ***
Comment 2 Wolfgang Bangerth 2006-03-08 05:11:08 UTC
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.
Comment 3 Kevin Atkinson 2007-04-16 04:53:31 UTC
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>)

Comment 4 Manuel López-Ibáñez 2011-10-22 14:45:22 UTC
(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.
Comment 5 Manuel López-Ibáñez 2012-03-21 13:21:53 UTC
Duplicated. The other bug has a better discussion.

*** This bug has been marked as a duplicate of bug 49152 ***