C语言尾调用优化历史揭秘
推荐指数 48.0 NO. 019 · 2026.08.11
发布2026/08/10Score94Comments74
为什么值得看
传统C调用约定要求调用者清理栈参数,导致编译器长期无法实现尾调用优化。直到调用约定变更后,C编译器才支持这一基础优化,解释了为何Python等语言迟迟未跟进。
编辑判断
很多年轻程序员以为尾调用优化是编译器的基操,但C语言的历史包袱说明这涉及ABI级别的妥协。Go语言至今拒绝实现TCO也是类似原因——为了保持栈轨迹的清晰性,宁可牺牲函数式编程风格。
这对AI基础设施开发者有现实影响:如果你在用C写高性能推理引擎或嵌入式运行时,手动trampoline还是比指望编译器更可靠。Julia和LuaJIT能做好TCO恰恰是因为它们控制了整条调用链,而不是绑定到C ABI上。
社区反馈
意见分歧 55 条评论
核心争论:TCO 应是语言标准强制特性还是编译器可选优化
and TCO was added then removed from js! https://stackoverflow.com/a/54721813 This leads to fun stack-overflow bugs too in a lot of js code (one solution is to flatten: https://joshua.hu/javascript-infinite-tail-call-recursion-st...)
Lack of TCO is also a common footgun for Scheme programmers using Common Lisp.
This footgun is the reason I'm so enthusiastic about the Rust `become` keyword. This proposal would give Rust a specific keyword which says that you intend TCO and so two things happen: 1. The compiler goes to more length to deliver TCO even where it wouldn't "just work" and 2. If it cannot deliver