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

--- Comment #13 from Jonathan Wakely <redi at gcc dot gnu.org> 2012-03-22 
11:02:29 UTC ---
Please don't close this as a dup of the caret diagnostics PR.

I agree there's no consensus on what should be done, but printing of
reconstructed expressions is utterly awful.  I think I qualify as a C++ expert
by almost any measure and am very familiar with G++ and its diagnostics, but I
frequently have to totally ignore G++ diagnostics because a single expression
is printed as 10 or more lines of unhelpful nested-name-specifiers and template
arguments. I just ignore the diagnostic and go back to the code to figure out
what's wrong without the compiler's help.

Re Gaby's point about the error appearing in a sub-expression of a larger full
expression, that's true, but the current behaviour doesn't help. The message in
comment 0 is unreadable and if it appears in a larger expression it would be
very difficult to determine which sub-expression the error came from, because
there is no resemblance to the original source.  The source says *first, the
message says first.__gnu_cxx::__normal_iterator<_Iterator,
_Container>::operator* which is not the same thing to users.  I'm using a
std::vector::iterator, WTF is __normal_iterator? How does printing that help? 
Oh, I see, right at the end of the line it refers to "val" so I can try to find
the relevant sub-expression, but by that point I've already clawed out my eyes
trying to look at the rest of the diagnostic.

Going back to point (3) in comment 0:  why is the left operand printed as
irrelevant crap about an iterator (when the relevant type is X&) but the right
operand printed as it appears in the source, not as a type?


Let's change the example slightly:

#include <vector>

struct Y { } val;

std::vector<Y>::iterator iter;

bool b = *iter == val;

4.7 gives:

t.cc:7:19: error: no match for 'operator==' in
'iter.__gnu_cxx::__normal_iterator<_Iterator, _Container>::operator*<Y*,
std::vector<Y> >() == val'

The problem is that Y is not equality comparable, it has nothing to do with
iterators, but more than 50% of the output refers to an iterator type which is
an implementation detail.  Also, the message is just bogus, WTF is
"operator*<Y*, std::vector<Y> >()" ?  That operator isn't a template function,
why does it have a template argument list?!

-fno-pretty-templates makes it less totally wrong:

t.cc:7:19: error: no match for 'operator==' in
'iter.__gnu_cxx::__normal_iterator<Y*, std::vector<Y, std::allocator<Y> >
>::operator*() == val'

Now at least we see the type printed correctly and no bogus template argument
list on a non-template member function.

Reply via email to