C++ 是否限制递归深度?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2630054/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Does C++ limit recursion depth?
提问by Narek
In Python there is a maximum recursion depth. Seems it is because Python is interpreted rather than compiled. Does C++ have the same concept? Or it is connected only with RAM limit?
在 Python 中存在最大递归深度。似乎是因为 Python 被解释而不是编译。C++ 有相同的概念吗?或者它只与RAM限制连接?
采纳答案by Donal Fellows
The limit in C++ is due to the maximum size of the stack. That's typically less than the size of RAM by quite a few orders of magnitude, but is still pretty large. (Luckily, large things like string contentsare typically held not on the stack itself.)
C++ 中的限制是由于堆栈的最大大小。这通常比 RAM 的大小小几个数量级,但仍然相当大。(幸运的是,像字符串内容这样的大东西通常不会保存在堆栈本身上。)
The stack limit is typically tunable at the OS level. (See the docs for the ulimit
shell built-in if you're on Unix.) The default on this machine (OSX) is 8 MB.
堆栈限制通常可在操作系统级别进行调整。(ulimit
如果您使用的是 Unix,请参阅内置 shell的文档。)这台机器 (OSX) 上的默认值是 8 MB。
[EDIT] Of course, the size of the stack doesn't entirely help by itself when it comes to working out how deep you can recurse. To know that, you have to compute the size of the activation record(or records) of the recursive function (also called a stack frame). The easiest way to do that (that I know of) is to use a disassembler (a feature of most debuggers) and to read out the size of the stack pointer adjustments at the start and end of every function. Which is messy. (You can work it out other ways –?for example, computing the difference between pointers to variables in two calls – but they're even nastier, especially for portable code. Reading the values out of the disassembly is easier IMO.)
[编辑] 当然,在计算递归深度时,堆栈的大小本身并不完全有帮助。要知道这一点,您必须计算递归函数(也称为堆栈帧)的激活记录(或记录)的大小。最简单的方法(我知道)是使用反汇编器(大多数调试器的功能)并在每个函数的开始和结束时读出堆栈指针调整的大小。这是乱七八糟的。(您可以通过其他方式解决——例如,计算两次调用中指向变量的指针之间的差异——但它们甚至更令人讨厌,尤其是对于可移植代码。从反汇编中读取值更容易 IMO。)
回答by Justin Ethier
No, C++ does not have an explicit recursion depth. If the maximum stack size is exceeded (which is 1 MB by default on Windows), your C++ program will overflow your stack and execution will be terminated.
不,C++ 没有明确的递归深度。如果超过最大堆栈大小(在 Windows 上默认为 1 MB),您的 C++ 程序将溢出堆栈并终止执行。
回答by Mike DeSimone
There's no recursion depth tracking or limit in the C or C++ standards. At runtime, the depth is limited by how big the stack can grow.
C 或 C++ 标准中没有递归深度跟踪或限制。在运行时,深度受堆栈可以增长的大小限制。
回答by Ignacio Vazquez-Abrams
C++ does have a maximum recursion depth, limited by the stack. However, modern operating systems are able to expand a userspace stack dynamically as it fills up, limiting recursion depth by memory space and memory fragmentation only.
C++ 确实有最大递归深度,受堆栈限制。然而,现代操作系统能够在用户空间堆栈填满时动态扩展它,仅通过内存空间和内存碎片来限制递归深度。
回答by Andy Shellam
I believe the limit is the size of the stack available on the platform. From what I've read, it's 8K8MB by default on Linux, but modern kernels can adjust the stack size dynamically.
我相信限制是平台上可用堆栈的大小。据我所知,Linux 上默认为8K8MB,但现代内核可以动态调整堆栈大小。
回答by Ken Bloom
Python has a tunable limiton recursive calls, while C++ is limited by the stack size.
Python对递归调用有可调限制,而 C++ 受堆栈大小限制。
Additionally, many languages or compilers can optimize tail recursion by removing the caller's stack frame so that no additional stack space is consumed. (In tail recursion, the only thing the calling function does is after making the recursive call is to return the recursive call's return value.)
此外,许多语言或编译器可以通过删除调用者的堆栈帧来优化尾递归,这样就不会消耗额外的堆栈空间。(在尾递归中,调用函数所做的唯一一件事就是在进行递归调用之后返回递归调用的返回值。)
int fact(int n, int accum=1){
if (n==0) return accum;
else return fact(n-1,n*accum); //tail recursion here.
}
Python does not optimize tail recursion (but stackless Pythondoes), and C++ does not require tail recursion optimization, but I believe that gcc optimizes tail recursion. The JVM does not optimize tail recursion, though the Scala language does in certain common documented cases. Scheme and Lisp (and probably other functional languages as well) require that tail recursion be optimized.
Python不优化尾递归(但是stackless Python可以),C++不需要尾递归优化,但是我相信gcc优化了尾递归。JVM 不会优化尾递归,尽管 Scala 语言在某些常见的记录情况下会这样做。Scheme 和 Lisp(可能还有其他函数式语言)需要优化尾递归。