Что означает «управление достигает конца непустотной функции»?

#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() .