Recursion 短路算子与尾部递归
假设我有这样一个简单的函数:Recursion 短路算子与尾部递归,recursion,compiler-optimization,tail-recursion,short-circuiting,Recursion,Compiler Optimization,Tail Recursion,Short Circuiting,假设我有这样一个简单的函数: 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){ 如果(len
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){
如果(len<1)返回TRUE;
返回*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);
}
int all_true(int*bools,int len){
如果(len<1)返回TRUE;
如果(!*bools)返回FALSE;
返回所有_true(布尔值+1,len-1);
}
从逻辑上讲,两者之间没有区别;假设bools
只包含TRUE
或FALSE
(合理定义),它们做的事情完全相同
我的问题是:如果编译器足够聪明,可以将第二个作为尾部递归调用进行优化,那么在“&&”短路的情况下,期望它以同样的方式优化第一个调用是否合理?显然,如果使用非短路运算符,这将不是尾部递归,因为两个表达式都将在运算符应用之前进行计算,但我对短路情况很好奇
(在我得到大量评论之前,我认为C编译器通常不优化尾部递归调用:考虑到这是一个关于用语言操作器来优化尾部递归调用的一般性问题,不依赖于语言。我很乐意重写这个方案,Haskell,OcAML,F.Yy,Python,或者,如果你这样做的话,你到底会怎么样?你的问题实际上是“编译器有多聪明?”但你没有说明你在使用哪个编译器
假设有一个合理的编译器在优化之前将源代码转换为中间流图,那么您编写的两段代码可以用相同的方式表示(虽然&&operator易于键入,但编译起来并不像&operator;那么简单,因此如果它在一个假设的编译器上以一个阶段展开,我也不会感到惊讶)。基于这个假设,可以合理地断言您的问题的答案是“是”
然而,如果你真的要依赖它,你应该用你正在使用的任何编译器来测试它。gcc确实优化了递归调用。