C 语言的尾调用优化其实很晚才出现
Tail-call optimization in C is relatively recent
很多人以为 C 语言早就支持尾调用优化,但事实并非如此。早期的 C 调用约定要求调用者清理栈帧,这直接阻碍了尾调用优化的实现。直到 2001 年,Mark Probst 才在 GCC 中通过特殊的调用约定实现了这一功能,但当时仍无法处理间接调用,这对解释器调度至关重要。近年来,随着 GCC 和 Clang 的进步,现代编译器已能处理此类优化。Xu 和 Kjolstad 在研究中利用这一特性处理了 10 万个代码片段,远超 Gforth 项目目前的规模。虽然 Python 社区率先应用了相关技术,但 C 语言生态的演进也让我们看到了更多可能性。
C 语言的调用约定一直是由调用者负责清理栈帧,这意味着如果 callee 移除参数,调用者就无法正常工作,从而将调用变成了非尾调用。