Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disable g++ "note candidates are.." compiler message

Tags:

c++

g++

Many times when I compile something with a typo or some other typing mismatch, I get the standard "error: no match for 'functionname' in ..." error. This is great. Then, especially in the case of overloaded functions and operators, g++ goes on and list like 10 pages of candidates which are just hideous and massive template definitions.

The error message is great, but is there any way to disable it from suggesting other functions variants?

like image 830
sshannin Avatar asked Jul 03 '12 14:07

sshannin


3 Answers

As far as I know, there is no compilation flag in GCC to disable the suggested candidates in case of ambiguous function calls.

Your only hope is perhaps to patch the GCC source code.

Digging in it (version: 4.7.1), I've found what appear to be the relevant function in gcc/cp/pt.c:

void
print_candidates(tree fns)
{
  const char *str = NULL;
  print_candidates_1 (fns, false, &str);
  gcc_assert (str == NULL);
}

As an educated guess, I think that you only need to comment out the function body.

like image 115
Gigi Avatar answered Nov 02 '22 14:11

Gigi


Does -Wfatal-errors do what you want?

It stops all errors after the first one, which is not the same as simply suppressing the candidate function notes, but it reduces the output significantly:

$ cat a.cc
void f() { }
void f(int) { }
void f(char) { }

int main()
{
  f((void*)0);
}
$ g++ a.cc
a.cc: In function ‘int main()’:
a.cc:7: error: call of overloaded ‘f(void*)’ is ambiguous
a.cc:2: note: candidates are: void f(int) <near match>
a.cc:3: note:                 void f(char) <near match>
$ g++ a.cc -Wfatal-errors
a.cc: In function ‘int main()’:
a.cc:7: error: call of overloaded ‘f(void*)’ is ambiguous
compilation terminated due to -Wfatal-errors.

Or, if you wanted to patch GCC, this adds a -fno-candidate-functions switch:

--- gcc/c-family/c.opt.orig 2012-07-11 16:37:29.373417154 +0000
+++ gcc/c-family/c.opt      2012-07-11 17:09:47.340418384 +0000
@@ -752,6 +752,10 @@
 fbuiltin-
 C ObjC C++ ObjC++ Joined

+fcandidate-functions
+C++ ObjC++ Var(flag_candidates) Init(1)
+-fno-candidate-functions Do not print candidate functions when overload resolution fails
+
 fcheck-new
 C++ ObjC++ Var(flag_check_new)
 Check the return value of new
--- gcc/cp/call.c.orig      2012-07-11 17:08:34.186424089 +0000
+++ gcc/cp/call.c   2012-07-11 17:09:51.843444951 +0000
@@ -3317,6 +3317,9 @@
   for (n_candidates = 0, cand1 = candidates; cand1; cand1 = cand1->next)
     n_candidates++;

+  if (!flag_candidates)
+    return;
+
   inform_n (loc, n_candidates, "candidate is:", "candidates are:");
   for (; candidates; candidates = candidates->next)
     print_z_candidate (loc, NULL, candidates);
--- gcc/cp/pt.c.orig        2012-07-11 16:37:35.658636650 +0000
+++ gcc/cp/pt.c     2012-07-11 17:10:20.910435942 +0000
@@ -1751,9 +1751,12 @@
 void
 print_candidates (tree fns)
 {
-  const char *str = NULL;
-  print_candidates_1 (fns, false, &str);
-  gcc_assert (str == NULL);
+  if (flag_candidates)
+    {
+      const char *str = NULL;
+      print_candidates_1 (fns, false, &str);
+      gcc_assert (str == NULL);
+    }
 }

 /* Returns the template (one of the functions given by TEMPLATE_ID)
like image 16
Jonathan Wakely Avatar answered Nov 02 '22 15:11

Jonathan Wakely


My answer is not as cool as a patch. If you want a less verbose error message, this script will remove the ugly code, and just leave the line number for the candidates.

g++ test.cc 2>&1 | sed 's/^\([^ ]*:[0-9]*: note\):.*/\1/'

So, it can be used in a script like this:

#!/bin/bash
GXX=/usr/bin/g++
ARGS=()
i=0
show_notes=yes
for arg in "$@" ; do
    if [ "$arg" = "-fterse-notes" ] ; then
        show_notes=no
    elif [ "$arg" = "-fno-terse-notes" ] ; then
        show_notes=yes
    else
        ARGS[$i]="$arg"
        i=$[i+1]
    fi
done
if [ $show_notes = yes ] ; then
    exec ${GXX} "${ARGS[@]}"
else
    exec ${GXX} "${ARGS[@]}" 2>&1 | sed 's/^\([^ ]*:[0-9]*: note\):.*/\1/'
fi

If the name of this script is g++ and in your path, it should work as if you have added a command line option called -fterse-notes.

like image 14
jxh Avatar answered Nov 02 '22 16:11

jxh