Gcc error control reaches end of non void function

I've been getting strange compiler errors on this binary search algorithm. I get a warning that control reaches end of non-void function. What does this mean? int binary(int val, int sorted[], int...

I’ve been getting strange compiler errors on this binary search algorithm. I get a warning that control reaches end of non-void function. What does this mean?

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;
}

detly's user avatar

detly

28.9k17 gold badges91 silver badges149 bronze badges

asked May 30, 2011 at 1:14

tekknolagi's user avatar

tekknolagitekknolagi

10.5k24 gold badges74 silver badges117 bronze badges

The compiler cannot tell from that code if the function will ever reach the end and still return something. To make that clear, replace the last else if(...) with just else.

answered May 30, 2011 at 1:16

rid's user avatar

4

The compiler isn’t smart enough to know that <, >, and == are a «complete set». You can let it know that by removing the condition «if(val == sorted[mid])» — it’s redundant. Jut say «else return mid;«

answered May 30, 2011 at 1:17

Ernest Friedman-Hill's user avatar

4

Error image

If the function is non-void,it means it has to return something before reaching the end of function block[ _} ].So, when we give only if and else-if statements the compiler cannot tell from that code,that any of these statements will be evaluated to true and return something.Means, if all of the condition evaluates to false,then the control will reach the end of function,without returning something,which is wrong.

answered Mar 30, 2021 at 12:38

Srijoy_paul's user avatar

Always build with at least minimal optimization. With -O0, all analysis that the compiler could use to determine that execution cannot reach the end of the function has been disabled. This is why you’re seeing the warning. The only time you should ever use -O0 is for step-by-line debugging, which is usually not a good debugging approach anyway, but it’s what most people who got started with MSVC learned on…

answered May 30, 2011 at 2:26

R.. GitHub STOP HELPING ICE's user avatar

3

I had the same problem. My code below didn’t work, but when I replaced the last «if» with «else», it works. The error was: may reach end of non-void function.

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'; 
        }

  }

answered Jan 6, 2014 at 5:23

Thuy's user avatar

ThuyThuy

1,4651 gold badge11 silver badges11 bronze badges

Make sure that your code is returning a value of given return-type irrespective of conditional statements

This code snippet was showing the same error

int search(char arr[], int start, int end, char value)
{
    int i;
    for(i=start; i<=end; i++)
    {
        if(arr[i] == value)
            return i;
    }
}

This is the working code after little changes

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;
}

answered Oct 24, 2020 at 13:11

Suraj Shende's user avatar

It means it’s searching for a function that needs to be completed.

else if(val == sorted[mid]) return mid;

so, remove the if() part and modify the code or add an else() at the end which returns an int.

answered Nov 7, 2020 at 10:22

Jayanth sattineni's user avatar

Compiler by itself would not know that the conditions you have given are optimum .. meaning of this is you have covered all cases ..
So therefore it always wants a return statement … So either you can change last else if with else or just write return 0 after last else if ;`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;
return 0; }`

answered Feb 4, 2021 at 12:39

Pankaj Ramola's user avatar

If it’s «main» function just make sure to return 0 or change it from
int main()
to
void main()

answered Apr 26, 2022 at 8:55

Niv's user avatar

NivNiv

7801 gold badge5 silver badges20 bronze badges

add to your code:

"#include < stdlib.h>"

return EXIT_SUCCESS;

at the end of main()

Ram Sharma's user avatar

Ram Sharma

8,6167 gold badges44 silver badges56 bronze badges

answered Jan 9, 2015 at 11:59

Donitsky's user avatar

2

  1. Use the return Statement at the End of the Function Body
  2. Use the return Statements at the End of Each Code Path of the Function Body

Solve Control Reaches End of Non-Void Function Error in C++

This article will explain several methods of solving control reaches end of non-void function error C++.

Use the return Statement at the End of the Function Body

Non-void functions are required to have a return type. Consequently, the function needs to have a statement that returns the object of the corresponding type. If certain compiler flags are passed, this type of error or warning might get suppressed entirely, which will lead to run-time faults if the given function gets called in the program.

The following example code has the reverseString function defined, which takes a reference to a string and returns the string value. If we look into a function body, there is no return statement. Even though the reverseString does not pass any arguments to the caller function, the compiler only displays the warning message, and the executable program is built anyway. If the function is called, then the control flow would most likely lead to a segmentation fault.

#include <iostream>
#include <algorithm>
#include <iterator>

using std::cout; using std::endl;
using std::string; using std::reverse;

string reverseString(string &s){
    string rev(s.rbegin(), s.rend());
}

int main() {
    string str = "This string is arbitrary";
    int cond = -1;

    cout << str << endl;
    cout << reverseString(str, cond) << endl;

    return EXIT_SUCCESS;
}

Use the return Statements at the End of Each Code Path of the Function Body

Another scenario where the control reaches the end of a non-void function is when the conditional blocks don’t have the return statements in every path. Thus, if the execution in the non-void function is branched and if statements don’t cover every possible path, then there needs to be an explicit return call at the end of the function body.

The next example demonstrates the string manipulation function with two conditional paths that pass the return value to the caller function. However, some cases are left not evaluated for the given condition, which implies that control flow might reach the end of the function block and cause run-time errors.

#include <iostream>
#include <algorithm>
#include <iterator>

using std::cout; using std::endl;
using std::string; using std::reverse;

string reverseString(string &s, int condition){
    if (condition == -1) {
        string rev(s.rbegin(), s.rend());
        return s;
    } else if (condition == 0) {
        return s;
    }
}

int main() {
    string str = "This string is arbitrary";
    int cond = -1;

    cout << str << endl;
    cout << reverseString(str, cond) << endl;

    return EXIT_SUCCESS;
}

You will possibly see the warning below.

Main.cpp:15:1: warning: non-void function does not return a value in all control paths [-Wreturn-type]
}
^
1 warning generated.

This problem comes from a misunderstanding of the flow of control in your algorithm. Here’s a representation of that control flow in pseudocode:

if (outer-condition-1)
    if (inner-condition-1)
        return 1
else if (outer-condition-2)
    if (inner-condition-2)
        return -1
else
    return 0

If you translate this into a flow chart, you will see why the compiler is yelling at you:

Flow chart

An else block is only ever related to one if...elseif...else construct at a time, so the last else block is attached only to the outer if conditions and not to the inner if conditions. If an outer condition evaluates to true and its inner condition evaluates to false, the else block will not be executed at all. This means the function will never encounter an explicit return statement, which is what the compiler doesn’t like; every function must always return something, no matter what input it receives.

There are a few ways to fix this. The most direct solution is to add a return statement at the end of the function, outside of the conditional statements, but that’s a bit sloppy—it can hide problems that would otherwise throw errors, making it a bit harder to find bugs.

Another way is to flatten your nested conditions, so that the pseudocode looks like this:

if (outer-condition-1 and inner-condition-1)
    return 1
else if (outer-condition-2 and inner-condition-2)
    return -1
else
    return 0

That might be appropriate if you’re sure your program is working as intended with the current setup. But if you need something unique to happen when an outer condition is satisfied and an inner condition is not satisfied, you need to keep the nested structure but deal directly with every possible outcome:

if (outer-condition-1)
    if (inner-condition-1)
        return 1
    else
        return 2
else if (outer-condition-2)
    if (inner-condition-2)
        return -1
    else
        return -2
else
    return 0

In either case, once the program reaches the first if statement, every path available to it will result in an explicit return statement, thus avoiding the control my reach end of non-void function message from Clang.

A related concept is «single entry, single exit» (SESE), which would demand that your function return a value only once at the end, rather than using the «early return» statements inside the conditional logic. This usually means defining an extra variable to hold the value that will be returned; for example:

declare int r
if (condition-1)
    r = 1
else if (condition-2)
    r = -1
else
    r = 0
return r

For those interested in a more detailed examination of the SESE concept, you can find a huge amount of discussion online and in programming texts; I like this question on programmers.SE, which contains a variety of stylistic and historical perspectives in its answers.

Понравилась статья? Поделить с друзьями:

Читайте также:

  • Gcc attribute error
  • Gboard как изменить цвет букв
  • Gbic security crypt 4 vn data crc error
  • Gbic invalid error detected on gi0 1 putting gi0 1 in err disable state
  • Gbak error size specification either missing or incorrect for file

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии