2013-02-07 14 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

刪除或更新鏈接。 –

相關問題