Search code examples
cif-statementrecursionreturn

Can you explain please, why I get "non-valid function does not return a value in all control paths" error if I use 'else if' instead of else? (C)


I'm learning implementing recursion in C programming language. In one of my simple programs I came across one particular error message, which I would like to understand and ask about, especially what's behind it. I was searching for the answer here, but I couldn't find the answer for the similar case, which I've got, so here is my question.

Can you explain please, why I am getting the "non-valid function does not return a value in all control paths" error if I use 'else if(condition)' instead od 'else' before the last 'return' inside the 'find_the_amount_of_smaller_numbers' function?

I understand it's related to the returning values, but shouldn't it work with 'else if(condition)' instead of 'else', if the condition is correct?

Please, explain it to me why this error occurs and please correct me and tell how to implement the condition to make it work by using just 'else if' with the proper condition.

Best regards

#include <stdio.h>

void print_hello_message(void);
int scan_the_main_value(void);
int find_the_amount_of_smaller_numbers(int main_value);
void print_closing_message(int smaller_value_counter);

void print_hello_message(void)
{
    printf("This program will count how many input values are smaller than the main value.\n");
}

int scan_the_main_value(void)
{
    int main_value; // to store the main value
    printf("Please specify the main value: ");
    scanf("%d", &main_value);
    
    printf("\nNow please input other values one by one, to be compare (type the main value again to stop):\n");
    
    return main_value;
}

int find_the_amount_of_smaller_numbers(int main_value)
{
    int compared_value;
    scanf(" %d", &compared_value);
    
    if (compared_value == main_value)   // ending condition
        return 0;
    else if (compared_value < main_value)
        return find_the_amount_of_smaller_numbers(main_value) + 1;
    else // if (compared_value > main_value)
        return find_the_amount_of_smaller_numbers(main_value);
}

void print_closing_message(int smaller_value_counter)
{
    printf("There are %d inputted smaller values than the main value.\n", smaller_value_counter);
}

int main(void)
{
    int main_value;
    int smaller_values_counter;
    
    print_hello_message();
    main_value = scan_the_main_value();
    smaller_values_counter = find_the_amount_of_smaller_numbers(main_value);
    print_closing_message(smaller_values_counter);
    
    return 0;
}

Solution

  • With this code:

        if (compared_value == main_value)   // ending condition
            return 0;
        else if (compared_value < main_value)
            return find_the_amount_of_smaller_numbers(main_value) + 1;
        else if (compared_value > main_value)
            return find_the_amount_of_smaller_numbers(main_value);
    

    the compiler you are using fails to derive the fact that at least one of the three conditions must be true, so it allows for the possibility that program control continues beyond these statements, in which case the function they are in would not return a value. Some compilers might do a better job of this, especially if optimization is enabled, but the C standard does not require them to do so.

    To avoid this, simply use else, not else if, for the final case, after verifying for yourself that it is correct.