How does this C int function works without a retur

2020-02-15 05:37发布

问题:

I've this C code which I was sure it wouldn't work, but it does.

#include <stdio.h>

int* find (int* a, int val) {
    if (*a == val)
        return a;
    else
        find(a+1, val);
}

int main() {
    int a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    int *b;

    b = find(a, 7);

    printf("%d\n", *b);

    return 0;
}

Of course, I get a warning from gcc since it lacks a return statement inside the else branch of the find function. However, it works perfectly.

Why does this happen? How does it know to return an int through the recursive function? Of course, the last calls returns an int, but I'm calling it in a void context.

回答1:

Assuming that you meant to write find instead of trova (I knew learning Italian would come in handy some day :), the answer is that this does not work perfectly. It "works" purely by chance, by virtue of undefined behavior.

Most likely, the deepest recursive call pushes the return value into some register, which the higher-level calls don't touch because they don't have a return statement, and when the caller inspects that register, the return value of the deepest call is still there. You can't rely on this, though.



回答2:

This code is not a valid C code, and the behavior of such code is not defined.

One reason why it work may be that there is no operation after the last call in find which may result in the return value of the recursive call staying in the return register (probably eax).

But again - the behavior is undefined.



回答3:

This seems to be working, but it is undefined behavior. It just happen that in your particular implementation/platform b takes the latest value returned from find. However, on a different implementation/platform this may as well crash.



回答4:

I can't find a reference, but I remember from years ago, in GCC, the return value register (as allocated on the CPU) always had the last return value, so if you computed some value and return with no value, the previous value persists. It seems like a bad practice to use this "feature".

Maybe see also

http://stackoverflow.com/questions/1610030/why-can-you-return-from-a-non-void-function-without-returning-a-value-without-pr

C: default return value if no value is given?

That says: Uniballer June 15th, 2012, 01:44 The behavior is undefined by the C language, because you didn't do in the function what you said you were going to do in the function declaration. In practice, on x86 the value of the function will be whatever happens to be in register eax on return.