假设我有一个像这样的简单函数:
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
(明智定义),则它们完全相同。
我的问题是:如果编译器足够聪明以优化第二个作为尾递归调用,那么期望它以相同的方式优化第一个是合理的,因为“&amp;&amp;”短路?显然,如果使用非短路运算符,这将不是尾递归的,因为两个表达式都会在运算符被应用之前进行求值,但我对短路是好奇的情况下。
(在我收到大量评论之前告诉我C编译器通常不会优化尾递归调用:认为这是一个关于使用短路运算符优化尾递归调用的一般性问题,与语言无关.I如果你不理解C,我会很乐意在Scheme,Haskell,OCaml,F#,Python中重写它,或者对你来说还有什么其他的东西。)
答案 0 :(得分:2)
你的问题真的是“编译器有多聪明?”但是你没有说明你正在使用哪个编译器。
假设一个假设合理的编译器在优化之前将源代码转换为中间流程图,你编写的代码片段可以用相同的方式表示(&amp;&amp;运算符,虽然方便键入,但不是几乎与&amp;运算符一样简单编译;所以如果它在一个假设的编译器的一个阶段扩展,我也不会感到惊讶)。在这种假设下,断言你的问题的答案是“是”是合理的。
但是,如果您真的要依赖它,那么您应该使用您正在使用的任何编译器来测试它。