短路操作员和尾递归

比方说,我有一个这样的简单功能:

int all_true(int* bools, int len) {
    if (len < 1) return TRUE;
    return *bools && all_true(bools+1, len-1);
}

这个函数可以用一个更明显的尾递归样式重写,如下所示:

int all_true(int* bools, int len) {
    if (len < 1) return TRUE;
    if (!*bools) return FALSE;
    return all_true(bools+1, len-1);
}

从逻辑上讲,两者之间没有差别; 假设bools只包含TRUEFALSE (明智地定义),它们完全一样。

我的问题是:如果一个编译器足够聪明,可以将第二个优化为尾递归调用,那么是否有理由期望它以同样的方式优化第一个,因为“&&”短路? 显然,如果使用非短路运算符,这不会是尾递归,因为在运算符被应用之前,两个表达式都将被评估,但我对短路情况很好奇。

(在我收到大量评论之前,我告诉我C编译器通常不会优化尾递归调用:考虑这是一个关于使用短语运算符优化尾递归调用的常见问题,与语言无关。很高兴能够在Scheme,Haskell,OCaml,F#,Python或者如果你不了解C的情况下重写这些内容。)


你的问题真的是“编译器有多聪明?” 但是你没有说明你正在使用哪个编译器。

给定一个假设的合理的编译器,在优化之前将源代码转换为中间流程图,您编写的代码片段可以用相同的方式表示(&&操作符,而方便键入,并不像&运算符;所以我不会感到惊讶,如果它在一个假设的编译器的一个阶段被扩展出来)。 根据这个假设,有理由断言你的问题的答案是“是”。

然而,如果你真的要依赖这个,你应该用你正在使用的任何编译器来测试它。

链接地址: http://www.djcxy.com/p/80595.html

上一篇: circuited operators and tail recursion

下一篇: splitting function in F#