2016-05-18 64 views
-6

使用GCC在Windows上編譯。它立即與Exception Code: c00000fd墜毀。爲什麼int main(){return main(); }導致stackoverflow而不是尾遞歸?

編輯:試着編譯下面的代碼(對於可見輸出),它會導致stackoverflow。

#include<stdio.h> 
int main(void) 
{ 
printf("Hello World\n"); 
return main(); 
} 

輸出 -

>gcc trailORoverflow.c -o trailORoverflow.exe 

Hello World 
Hello World 
Hello World 
Hello World 
Hello World 
Hello World 

它使打印的Hello World的某個時候和崩潰。

編輯:未碰撞O2,O3-O1 -foptimize-sibling-calls優化。

+0

也許正確的答案與尾調用遞歸有關。 iirc GCC將實施尾部呼叫遞歸,即在可能的情況下優化遞歸呼叫 – dreadiscool

+1

因爲C標準不需要特定的優化。 (它甚至不需要爲局部變量使用堆棧)。並使用正確的原型風格的函數聲明器:'main(void)'。 – Olaf

+0

用不同的優化標誌試試gcc肯定有意義,可能某些組合會給你無限循環,你想要 –

回答

2

您顯示的代碼將無限期地調用main,因此會導致堆棧溢出。在任何功能的情況下都是如此,而不是針對main的。每個函數調用一個堆棧框架都會在內存中創建,並且隨着遞歸深入而創建無限的這樣的框架,您將獲得一個stackoverflow。

但是,如果你做了一個適當的基本終止,如下例所示,對於main中的遞歸調用,那麼有一個有趣的事情。

int main (void) 
{ 
    static int x = 100; 

    if (x == 0) 
    { 
    return 0; 
    } 
    x--; 
    printf ("%d\n", x); 
    main(); 
    return 0; 
} 

有在C和C++語言調用main遞歸的差異,我認爲這是有趣的指出這一點。這裏是我寫的post,我給出了一些解釋。

C++標準談論這些在

第3.6.1節第3款

Recursive calls are permitted, except to the function named main. 

和第5.2.2節第9

The function main shall not be used within the program. … … … 

我沒有發現在任何這樣的限制C標準。我發現有關在C99標準的遞歸調用中第6.5.2.2節的第11段如下:

Recursive function calls shall be permitted, both directly and indirectly through any chain of other functions. 

因此呼籲主要遞歸在C語言中是確定性的。但按照C++標準,不允許從任何函數或遞歸調用main。

相關問題