假设我有一个像这样的简单函数:
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,你会用什么别的什么东西。)