nofe
nofe

Reputation: 408

recursive functions in C: is return always necessary?

this is my first time playing with recursive functions, and this function that I wrote returns the size of a string if it contains only letters in ascending order, and if not it returns -1.

I don't understand why it works for both codes, after I took out the second "return". Is one more wasteful than the other? Would appreciate some insight.

with "return only_ascending_letters(string, index+1);"

 #include <stdio.h>

    int only_ascending_letters(char string[], int index);

    void main() {
        char string1[]="Hi my name is pete";
        char string2[]="aabcdefg";

        printf("the first string is %d and the second one is %d\n",only_ascending_letters(string1,0),only_ascending_letters(string2,0));

    }

    int only_ascending_letters(char string[], int index){
        if(!string[index]) return index;
        if(((string[index]>='a'&&string[index]<='z')||(string[index]>='A'&&string[index]<='Z'))&&((string[index]<=string[index+1])||!string[index+1])) 
            return only_ascending_letters(string, index+1);
        else return -1;

    }

with "only_ascending_letters(string, index+1);"

 #include <stdio.h>

    int only_ascending_letters(char string[], int index);

    void main() {
        char string1[]="Hi my name is pete";
        char string2[]="aabcdefg";

        printf("the first string is %d and the second one is %d\n",only_ascending_letters(string1,0),only_ascending_letters(string2,0));

    }

    int only_ascending_letters(char string[], int index){
        if(!string[index]) return index;
        if(((string[index]>='a'&&string[index]<='z')||(string[index]>='A'&&string[index]<='Z'))&&((string[index]<=string[index+1])||!string[index+1])) 
        /*Took out the return*/ only_ascending_letters(string, index+1);
        else return -1;

    }

Upvotes: 3

Views: 1206

Answers (3)

Steve Atkinson
Steve Atkinson

Reputation: 1239

You have two exit conditions. You either run off the end of the string, in which case your condtion of ascending characters is met and you return the length of the string, or you find a character that fails your ascending test, in which case you return -1.

Not returning the value from the call to the recursive function may work on some implementations of the compiler but with a different compiler or different optimisation flags, it may well not work so you should keep the return in your code.

Upvotes: 0

aib
aib

Reputation: 46921

First of all, main() returns an int (actually, a type compatible with int).

Second, you should format your code more. Whitespace is your friend, as are line breaks. It was hard to tell whether the code without return was actually correct because most of it ran offscreen.

Third, you should always work with all [reasonable] warnings enabled. Doing so would have caught the missing return condition, as well as the void main().

As for the answer, @jpalecek has done a great job providing it. I would only like to add that undefined behavior is a beast. If you rely on it, a "working" program may stop doing so just because you decided to compile it again, played some music while running it, or the phase of the moon changed.

All I could find in the [99] standard was §6.9.1 clause 12:

If the } that terminates a function is reached, and the value of the function call is used by the caller, the behavior is undefined.

Upvotes: 1

jpalecek
jpalecek

Reputation: 47762

Yes, you absolutely need the return. Note that C language rules are a bit lax about this issue, and if you hadn't used the return value, it would be fine without it. However, you use the return value, so you need the return statement.

What you see is probably caused by the implementation detail that function on some architectures return (integral values) by setting a well known register to that value (eax on i386). Therefore, if the bottommost recursive call does return and set this register, and the calls in-between don't stomp on that register, you see that it sort of works. However, you mustn't rely on that.

Note that good compilers will recognize this is a tail-recursive call and compile both variant basically the same way.

Upvotes: 7

Related Questions