#c #warnings #compiler-warnings
#c #предупреждения #предупреждения компилятора
Вопрос:
Я получаю странные ошибки компилятора в этом алгоритме двоичного поиска. Я получаю предупреждение о том, что control reaches end of non-void function
. Что это значит?
int binary(int val, int sorted[], int low, int high) {
int mid = (low high)/2;
if(high < low)
return -1;
if(val < sorted[mid])
return binary(val, sorted, low, mid-1);
else if(val > sorted[mid])
return binary(val, sorted, mid 1, high);
else if(val == sorted[mid])
return mid;
}
Ответ №1:
Компилятор не может определить из этого кода, достигнет ли функция когда-либо конца и всеравно что-то вернет. Чтобы прояснить это, замените последнее else if(...)
на просто else
.
Комментарии:
1. (И причина, по которой компилятор напуган, заключается в том, что функция, введенная для возврата an,
int
должна действительно возвращатьint
, а не просто выпадать из конца функции)2. Спасибо! это имеет смысл! не приведет ли это к чему-то нежелательному?
3. @tekknolagi, ну, логика для нас, людей, совершенно ясна:
val
может быть только<
,>
или==
кsorted[mid]
, альтернативы действительно нет… Таким образом, он не может перехватить что-либо еще, если это вся логика.4. Другой способ избавиться от предупреждения — добавить
assert(false);
в конце функции, чтобы четко сообщить компилятору (и читателю-пользователю), что вы намеренно опустили регистр else , потому что вы уверены, что этого не может произойти.
Ответ №2:
Компилятор недостаточно умен, чтобы знать, что <
, >
и ==
являются «полным набором». Вы можете сообщить ему об этом, удалив условие «if(val == sorted[mid])» — оно избыточно. Просто скажи « else return mid;
«
Комментарии:
1. Компилятор достаточно умен. Проблема в том, что пользователь был недостаточно умен, чтобы указать ненулевой уровень оптимизации.
-O0
почти всегда это очень, очень плохая идея.2. Интересная идея, но я думаю, что нет. Например,
gcc
выдает эту ошибку с-O3
.3. Действительно, я подтвердил с помощью gcc 4.5.2.
4. Кроме того, я протестировал добавление
printf
вызова в конце функции, и gcc фактически генерирует для него код. Так или иначе, он не определяет эту точку как недостижимую…
Ответ №3:
Если функция непустотная, это означает, что она должна вернуть что-то до достижения конца функционального блока[ _} ]. Итак, когда мы даем только инструкции if и else-if, компилятор не может определить из этого кода, что любое из этих утверждений будет оценено как true и вернет что-то.Означает, что если все условия оцениваются как false, то управление достигнет конца функции, не возвращая ничего, что является неправильным.
Ответ №4:
Всегда создавайте с хотя бы минимальной оптимизацией. При -O0
весь анализ, который компилятор мог бы использовать, чтобы определить, что выполнение не может достичь конца функции, был отключен. Вот почему вы видите предупреждение. Единственный раз, который вам когда-либо следует использовать -O0
, — это для пошаговой отладки, которая обычно в любом случае не является хорошим подходом к отладке, но это то, чему научилось большинство людей, которые начали работать с MSVC…
Комментарии:
1. Я скептически отношусь к этому.
gcc
4.0.1 выдает это предупреждение при полной оптимизации. Знаете ли вы конкретный компилятор, оптимизация которого позволила бы убрать это сообщение?2. Я не пробовал этот конкретный код, но в целом gcc хорош в обнаружении недоступного кода. Интересно, есть ли какое-то тайное соображение о сглаживании, которое делает невозможным гарантировать, что конец функции недоступен…
3. Действительно. Я был бы рад услышать, что происходит. На самом деле это превратилось в довольно интересный вопрос о поведении gcc.
Ответ №5:
У меня была такая же проблема. Мой приведенный ниже код не сработал, но когда я заменил последнее «if» на «else», это сработало. Ошибка заключалась в том, что может быть достигнут конец непустотной функции.
int shifted(char key_letter)
{
if(isupper(key_letter))
{
return key_letter - 'A';
}
if(islower(key_letter) //<----------- doesn't work, replace with else
{
return key_letter - 'a';
}
}
Ответ №6:
Убедитесь, что ваш код возвращает значение заданного возвращаемого типа независимо от условных выражений
Этот фрагмент кода показывал ту же ошибку
int search(char arr[], int start, int end, char value)
{
int i;
for(i=start; i<=end; i )
{
if(arr[i] == value)
return i;
}
}
Это рабочий код после небольших изменений
int search(char arr[], int start, int end, char value)
{
int i;
int index=-1;
for(i=start; i<=end; i )
{
if(arr[i] == value)
index=i;
}
return index;
}
Ответ №7:
Это означает, что он ищет функцию, которая должна быть завершена.
else if(val == sorted[mid]) return mid;
итак, удалите часть if() и измените код или добавьте else() в конце, которая возвращает значение int.
Ответ №8:
Компилятор сам по себе не будет знать, что заданные вами условия являются оптимальными .. смысл этого в том, что вы рассмотрели все случаи.. Поэтому ему всегда требуется оператор return … Итак, вы можете либо изменить last else if на else, либо просто написать return 0 после last else if ;`int binary(int val, int sorted[], int low, int high) { int mid = (низкий высокий) /2;
if(high < low)
return -1;
if(val < sorted[mid])
return binary(val, sorted, low, mid-1);
else if(val > sorted[mid])
return binary(val, sorted, mid 1, high);
else if(val == sorted[mid])
return mid;
return 0; }`
Ответ №9:
Если это функция «main», просто убедитесь, что она возвращает 0 или измените ее с int main() на void main()
Ответ №10:
добавьте в свой код:
"#include < stdlib.h>"
return EXIT_SUCCESS;
в конце main()
Комментарии:
1. Это сработало, хотя за него проголосовали с понижением. Это гарантирует, что функция возвращает что-то, чтобы компилятор не выдавал ошибок.
2. эта проблема может вызвать эту ошибку, но этот вопрос не о
main()
, он касается другой формы ошибки. другие вопросы по stackoverflow говорят об этой ошибке вmain()
.