简体   繁体   English

没有return语句的C int函数如何工作?

[英]How does this C int function works without a return statement?

I've this C code which I was sure it wouldn't work, but it does. 我有这个C代码,我确定它不会起作用,但是确实可以。

#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. 当然,我从gcc收到警告,因为它在find函数的else分支内缺少return语句。 However, it works perfectly. 但是,它运行完美。

Why does this happen? 为什么会这样? How does it know to return an int through the recursive function? 如何知道通过递归函数返回int? Of course, the last calls returns an int, but I'm calling it in a void context. 当然,最后一次调用返回一个int,但是我在一个void上下文中调用它。

This code is not a valid C code, and the behavior of such code is not defined. 该代码不是有效的C代码,并且未定义此类代码的行为。

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). 它起作用的一个原因可能是, find的最后一个调用之后没有任何操作,这可能导致递归调用的返回值保留在返回寄存器中(可能是eax)。

But again - the behavior is undefined . 但同样-行为是不确定的

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 . 碰巧在您的特定实现/平台b中使用了find返回的最新值。 However, on a different implementation/platform this may as well crash. 但是,在其他实现/平台上,这也可能会崩溃。

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. 假设您打算写find而不是trova (我知道有一天学习意大利语会派上用场:),答案是这并不完美。 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. 但是,您不能依靠它。

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. 我找不到参考,但是我记得几年前,在GCC中,返回值寄存器(在CPU上分配的)始终具有最后一个返回值,因此,如果您计算了一些值而没有返回值,则前一个价值依然存在。 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 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? C:如果没有给出值,则默认返回值?

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. 也就是说:Uniballer,2012年6月15日,01:44 C语言未定义行为,因为您没有在函数中执行您打算在函数声明中执行的操作。 In practice, on x86 the value of the function will be whatever happens to be in register eax on return. 实际上,在x86上,函数的值将是返回时寄存器eax中的任何值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM