Отключить g++ "примечание кандидатов..." компилятор сообщение - программирование

Отключить g++ "примечание кандидатов..." компилятор сообщение

Много раз, когда я скомпилировал что-то с опечаткой или каким-то другим несоответствием ввода, я получаю стандартную ошибку "error: no match for" functionname in in... ". Отлично. Затем, особенно в случае перегруженных функций и операторов, g++ продолжается и перечисляется как 10 страниц кандидатов, которые являются просто отвратительными и массивными определениями шаблонов.

Сообщение об ошибке велико, но есть ли способ отключить его от предложения других вариантов функций?

4b9b3361

Ответ 1

Насколько я знаю, в GCC отсутствует флаг компиляции, чтобы отключить предложенные кандидаты в случае неоднозначных вызовов функций.

Ваша единственная надежда - это, возможно, исправить исходный код GCC.

Копая в нем (версия: 4.7.1), я нашел то, что кажется релевантной функцией в gcc/cp/pt.c:

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

Как явное обоснование, я думаю, что вам нужно только прокомментировать тело функции.

Ответ 2

Мой ответ не такой классный, как патч. Если вам требуется менее подробное сообщение об ошибке, этот script удалит уродливый код и просто оставьте номер строки для кандидатов.

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

Таким образом, его можно использовать в script следующим образом:

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

Если имя этого script равно g++ и в вашем пути, оно должно работать так, как если бы вы добавили параметр командной строки под названием -fterse-notes.

Ответ 3

Выполняет ли -Wfatal-errors то, что вы хотите?

Он останавливает все ошибки после первого, что не то же самое, что просто подавление заметок-кандидатов, но значительно сокращает вывод:

$ 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.

Или, если вы хотите установить GCC, это добавит переключатель -fno-candidate-functions:

--- 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)