为什么 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 一段时间然后崩溃。

编辑:O2O3-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。