2013-02-07 12 views
0

我有这个C代码,我确信它不会工作,但它确实。这个C int函数如何在没有返回语句的情况下工作?

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

当然,我从海湾合作委员会的警告,因为它缺乏find功能的else分支内return语句。但是,它完美地工作。

为什么会发生这种情况?它如何知道通过递归函数返回一个int?当然,最后一次调用返回一个int,但我在无效的环境中调用它。

+1

什么是'trova'? – asm

+1

只要你拒绝告诉我们'trova'是什么,你如何期待一个有意义的答案?就我们所知,它立即调用'exit(0);'。 –

+2

它不编译,程序中没有'trova'函数定义。粘贴可编译的测试代码。 – ouah

回答

2

假设你的意思是写find而不是trova(我知道学习意大利语有一天会派上用场:)但答案是,这并不完美。由于未定义的行为,它纯粹是偶然的“起作用”。

最有可能的是,最深的递归调用将返回值推入某个寄存器中,较高层调用不会触及,因为它们没有返回语句,并且当调用者检查该寄存器时,返回值最深的电话仍然存在。不过,你不能依赖这个。

3

这个好像可以工作,但它是未定义的行为。它恰好发生在你的特定实现/平台b采用从find返回的最新值。但是,在不同的实现/平台上,这可能会崩溃。

+0

更具体一点:'return a'具有设置返回寄存器不会被清除的副作用。 *但这是未定义的行为*,是 – ckruse

7

此代码不是有效的C代码,并且此类代码的行为未定义。

原因之一,它的工作可能是存在find最后一次通话后没有操作这可能导致递归调用留在返回寄存器(可能EAX)的返回值。

但同样 - 行为不明确

-1

我找不到一个引用,但我记得从几年前开始,在GCC中,返回值寄存器(在CPU上分配)总是有最后一个返回值,所以如果你计算了一些值并返回没有值,以前的值仍然存在。使用这个“功能”似乎是一个不好的做法。

也许又见

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?

,上面写着: Uniballer 2012年6月15日,01:44 行为是由C语言不确定的,因为你没有在函数中做你说你打算在函数声明中做什么。实际上,在x86上,函数的值将是返回时在寄存器eax中发生的任何事情。

+0

删除或更新链接。 –

相关问题