This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/49152] Unhelpful diagnostic for iterator dereference
- From: "redi at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Thu, 22 Mar 2012 11:02:29 +0000
- Subject: [Bug c++/49152] Unhelpful diagnostic for iterator dereference
- Auto-submitted: auto-generated
- References: <bug-49152-4@http.gcc.gnu.org/bugzilla/>
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.