kos*_*hei 6 recursion tail-recursion short-circuiting compiler-optimization
假设我有一个像这样的简单函数:
int all_true(int* bools, int len) {
if (len < 1) return TRUE;
return *bools && all_true(bools+1, len-1);
}
Run Code Online (Sandbox Code Playgroud)
这个函数可以用更明显的尾递归样式重写,如下所示:
int all_true(int* bools, int len) {
if (len < 1) return TRUE;
if (!*bools) return FALSE;
return all_true(bools+1, len-1);
}
Run Code Online (Sandbox Code Playgroud)
从逻辑上讲,两者之间没有差别; 假设bools
只包含TRUE
或FALSE
(明智地定义),它们完全相同.
我的问题是:如果编译器足够智能以优化第二个作为尾递归调用,那么假设它以相同的方式优化第一个是合理的,假设"&&"短路?显然,如果使用非短路运算符,这将不是尾递归的,因为两个表达式都会在运算符被应用之前进行求值,但我对短路情况感到好奇.
(在我收到大量评论告诉我C编译器通常不优化尾递归调用之前:考虑这是一个关于使用短路运算符优化尾递归调用的一般性问题,不依赖于语言.我将是很高兴在Scheme,Haskell,OCaml,F#,Python中重写这个,或者如果你不理解C,那么你还有什么其他的东西.)
你的问题实际上是“编译器有多聪明?” 但你没有说明你正在使用哪个编译器。
假设有一个合理的编译器,它在优化之前将源代码转换为中间流程图,您编写的两个代码片段都可以以相同的方式表示(&& 运算符虽然易于键入,但编译起来并不像& 运算符;所以如果它在假设的编译器上在一个阶段中扩展,我不会感到惊讶)。基于这个假设,可以合理地断言你的问题的答案是“是”。
但是,如果您确实要依赖于此,则应该使用您碰巧使用的任何编译器来测试它。