为什么 int main() { return main();导致计算器溢出而不是尾递归?
Why does int main() { return main(); } cause stackoverflow and not tail recursion?
使用 GCC 在 Windows 上编译。它立即崩溃 Exception Code: c00000fd
.
编辑:尝试编译以下代码(用于可见输出)并导致计算器溢出。
#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
优化没有崩溃。
您显示的代码将无限调用 main
,因此会导致堆栈溢出。这在任何函数的情况下都是如此,而不是特定于 main。每个函数调用都会在内存中创建一个堆栈帧,并且随着递归的深入会创建无限的此类帧,您会得到一个 Whosebug。
但是,如果您像下面的示例那样进行适当的基础终止,对于 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 标准中没有发现任何此类限制。我在第 6.5.2.2 节第 11 段中找到的有关 C99 标准中的递归调用的内容如下
Recursive function calls shall be permitted, both directly and indirectly through any chain of other functions.
因此在C语言中递归调用main是确定性的。但是根据 C++ 标准,不允许从任何函数或递归调用 main。
使用 GCC 在 Windows 上编译。它立即崩溃 Exception Code: c00000fd
.
编辑:尝试编译以下代码(用于可见输出)并导致计算器溢出。
#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
优化没有崩溃。
您显示的代码将无限调用 main
,因此会导致堆栈溢出。这在任何函数的情况下都是如此,而不是特定于 main。每个函数调用都会在内存中创建一个堆栈帧,并且随着递归的深入会创建无限的此类帧,您会得到一个 Whosebug。
但是,如果您像下面的示例那样进行适当的基础终止,对于 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 标准中没有发现任何此类限制。我在第 6.5.2.2 节第 11 段中找到的有关 C99 标准中的递归调用的内容如下
Recursive function calls shall be permitted, both directly and indirectly through any chain of other functions.
因此在C语言中递归调用main是确定性的。但是根据 C++ 标准,不允许从任何函数或递归调用 main。