https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67499
Manuel López-Ibáñez <manu at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |manu at gcc dot gnu.org --- Comment #5 from Manuel López-Ibáñez <manu at gcc dot gnu.org> --- There are several ways this output could be "easily" improved: 1) One problem with GCC's output is that it becomes difficult to track where each candidate is listed in the wall of text. We could print something like (also currently the candidates are not actually quoted, which is unusual when printing source code): note: candidate 1: %qD ... note: candidate 2: %qD 2) Also, we print two times the same include stack for two different candidates because we print a candidate from a different file in the middle. In file included from /usr/include/c++/4.8/ostream:612:0, from /usr/include/c++/4.8/iostream:39, from test.cc:1: /usr/include/c++/4.8/bits/ostream.tcc:91:5: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(short int) [with _CharT = char; _Traits = std::char_traits<char>] basic_ostream<_CharT, _Traits>:: ^ /usr/include/c++/4.8/bits/ostream.tcc:91:5: note: no known conversion for argument 1 from ‘foo’ to ‘short int’ In file included from /usr/include/c++/4.8/iostream:39:0, from test.cc:1: /usr/include/c++/4.8/ostream:181:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(short unsigned int) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_ostream<_CharT, _Traits>::__ostr eam_type = std::basic_ostream<char>] operator<<(unsigned short __n) ^ /usr/include/c++/4.8/ostream:181:7: note: no known conversion for argument 1 from ‘foo’ to ‘short unsigned int’ In file included from /usr/include/c++/4.8/ostream:612:0, from /usr/include/c++/4.8/iostream:39, from test.cc:1: /usr/include/c++/4.8/bits/ostream.tcc:105:5: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(int) [with _CharT = char; _Traits = std::char_traits<char>] basic_ostream<_CharT, _Traits>:: ^ This is a lot of repetitive noise. The candidates could be sorted to reduce this noise. 3) We print the reason in a different line than the candidate, with the caret line in the middle. Thus, the caret line does not serve as a visual separation between candidates. /usr/include/c++/4.8/ostream:232:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long double) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>] operator<<(long double __f) ^ /usr/include/c++/4.8/ostream:232:7: note: no known conversion for argument 1 from ‘foo’ to ‘long double’ /usr/include/c++/4.8/ostream:245:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(const void*) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>] operator<<(const void* __p) ^ /usr/include/c++/4.8/ostream:245:7: note: no known conversion for argument 1 from ‘foo’ to ‘const void*’ Instead, we could print the reason after the candidate, perhaps even within the same line. Maybe: /usr/include/c++/4.8/ostream:232:7: note: candidate 5: no known conversion for argument 1 from ‘foo’ to ‘long double’ for 'std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long double) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]' operator<<(long double __f) ^ /usr/include/c++/4.8/ostream:245:7: note: candidate 6: no known conversion for argument 1 from ‘foo’ to ‘const void*’ for 'std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(const void*) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]' operator<<(const void* __p) ^ 4) The candidate output is too verbose in some cases: /usr/include/c++/4.8/ostream:548:5: note: template<class _Traits> std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, const unsigned char*) operator<<(basic_ostream<char, _Traits>& __out, const unsigned char* __s) ^ /usr/include/c++/4.8/ostream:548:5: note: template argument deduction/substitution failed: test.cc:5:18: note: cannot convert ‘bar’ (type ‘foo’) to type ‘const unsigned char*’ std::cout << bar; ^ The above could simply say: /usr/include/c++/4.8/ostream:548:5: note: template<class _Traits> std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, const unsigned char*) operator<<(basic_ostream<char, _Traits>& __out, const unsigned char* __s) ^ /usr/include/c++/4.8/ostream:548:5: note: template argument deduction/substitution failed: cannot convert type ‘foo’ to type ‘const unsigned char*’ 5) We could limit the number of candidates with a new option (-fcandidates-limit=N) similar to -ftemplate-backtrace-limit=, with a conservative value of 10 and printing a message "note: %d additional candidates not shown, use -fcandidates-limit=0 to show all candidates" Perhaps this could be Google Summer of Code project. Otherwise, I guess it will not get implemented for lack of time/manpower.