2012-07-03 3 views
20

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

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

+19

Ждать, вы хотите, чтобы сообщение об ошибке имело * меньше * информации? –

+7

Определения функций, которые он предлагает, скрыты за 10 слоями шаблонов (особенно с повышением) и затрудняют поиск того, где компилятор действительно идентифицирует строку с ошибкой. Я хочу, чтобы он рассказал мне, где была ошибка, и что было не так, но мне не нужно ее предлагать, как ее исправить. – sshannin

+4

пропустите его через grep, только совпадение на линиях, у которых есть «ошибка:» в них? FWIW моя среда разработки имеет «переход к строке с ошибкой» как функцию, которая в качестве добавленного бонуса оставляет верхнюю часть списка кандидатов, отображаемых на экране. – Flexo

ответ

13

Насколько я знаю, в 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); 
} 

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

+0

+1 для двойного LOL. Сначала я подумал, что это всего лишь изнурительные ответы. Тогда я понял, что с gcc это * common *, чтобы построить компилятор из источника, и что когда-то я это знал, единственное, что меня сейчас озадачивает, - это очевидная современная глава функции C/C++. Как я помню (но, возможно, я ошибаюсь) старый синтаксис K & R C везде? –

+0

@ Cheersandhth.-Alf Это был первый раз, когда я посмотрел на базу кода GCC, и это, вероятно, _too clean_ для проекта такого размера. Что касается синтаксиса K & R C, то я уже слишком 10 лет даже знать, что это такое :) – Gigi

+0

@ Cheersandhth.-Alf да! Код сильно изменился, некоторые возможности C++ даже разрешены с мая 2010 года. И я согласен с тем, что база кода на самом деле удивительно ясна! – log0

10

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

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

Таким образом, он может быть использован в сценарии, как это:

#!/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 

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

+0

Конечно, вы хотите только увеличить $ i внутри сначала «еще»? – cdyson37

+1

@ cdyson37: Я на самом деле формирую новый список аргументов, выводящих вхождения '-fterse-notes' и' -fno-terse-notes'. 'bash', похоже, обрабатывает то, что я написал хорошо, но, возможно, более технически правильная реализация заключалась бы в том, чтобы только увеличивать его в разделе' else' после оператора 'ARGS [$ i] =" $ arg ". – jxh

10

-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) 
Смежные вопросы