Mac OS X 上 Rust 的递归深度太浅

Recursion depth too shallow in Rust on Mac OS X

fn recu(n: int) {
    println!("{}", n);
    recu(n+1)
}

fn main() {
    recu(0)
}

输出:

...
2924
2925
2926
2927
2928
2929
2930
2931

thread '<main>' has overflowed its stack
[1]    23873 illegal hardware instruction  ./test

信息:

rustc 1.0.0-nightly (ea6f65c5f 2015-01-06 19:47:08 +0000)

MacBook Pro

2.2 GHz Intel Core i7

在其他机器上(Linux 64):

11668
11669
11670

thread '<main>' has overflowed its stack
[1]    18070 illegal hardware instruction (core dumped)  ./test

注意 11670/2931 几乎正好等于 4 - 也就是说,Linux 上的堆栈帧数几乎是 OS X 上的四倍。显然,你的 Mac OS X 的筹码量是 Linux 的默认筹码量的 1/4。这与 Rust 无关,等效的 C 程序会产生大致相同的结果。您可以从命令行 运行 ulimit -s 确认 OS 之间的堆栈大小差异。

LLVM 应该能够尾调用优化这个特定的程序。使用 -O 标志尝试 运行ning rustc。如果这可行,这将允许无限递归。 LLVM 将生成一个 recu 函数,而不是调用自身,而是在设置 n 后循环回到它自己的开始,允许它在不消耗堆栈的情况下递归 space.

在我自己的测试中,为了让它永远递归,我不得不将程序修改成这样,可能是因为 println! 宏隐藏了析构函数:

fn recu(n: int) {
    printint(n);
    recu(n+1)
}

#[inline(never)]
fn printint(n: int) {
    println!("{}", n);
}

fn main() {
    recu(0)
}