短路操作员和尾递归
比方说,我有一个这样的简单功能:
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
只包含TRUE
或FALSE
(明智地定义),它们完全一样。
我的问题是:如果一个编译器足够聪明,可以将第二个优化为尾递归调用,那么是否有理由期望它以同样的方式优化第一个,因为“&&”短路? 显然,如果使用非短路运算符,这不会是尾递归,因为在运算符被应用之前,两个表达式都将被评估,但我对短路情况很好奇。
(在我收到大量评论之前,我告诉我C编译器通常不会优化尾递归调用:考虑这是一个关于使用短语运算符优化尾递归调用的常见问题,与语言无关。很高兴能够在Scheme,Haskell,OCaml,F#,Python或者如果你不了解C的情况下重写这些内容。)
你的问题真的是“编译器有多聪明?” 但是你没有说明你正在使用哪个编译器。
给定一个假设的合理的编译器,在优化之前将源代码转换为中间流程图,您编写的代码片段可以用相同的方式表示(&&操作符,而方便键入,并不像&运算符;所以我不会感到惊讶,如果它在一个假设的编译器的一个阶段被扩展出来)。 根据这个假设,有理由断言你的问题的答案是“是”。
然而,如果你真的要依赖这个,你应该用你正在使用的任何编译器来测试它。
链接地址: http://www.djcxy.com/p/80595.html