返回

文章详情

C语言中的尾调用优化相对较新

Hacker News2026年8月10日 11:34

C语言中的尾调用优化相对较新。发表于2025年8月21日22:11 UTC(星期四),作者:anton(订阅者,#25547)。父文章:Python、尾调用和性能。实际上,C语言中的尾调用并不是一直存在的。C语言的调用约定是被调用者并不删除调用者放在栈上的任何内容。调用者可以看到声明int f();,实际的调用可以有n>0个参数,而实际的函数可以有m≤n个参数。如果被调用者删除了参数,这将不会一直有效。所以调用者必须在调用和随后的返回之间删除参数,从而将调用转换为非尾调用。当我在1994年查看当时的C编译器时,它们并未针对文章中展示的使用方式执行尾调用优化。2001年,Mark Probst在GCC中实现了尾调用优化,并使用了一个独立的调用约定;他在第6.4节中列出了当时GCC中现有的尾调用优化的限制,其中之一是:“它无法处理间接调用”(这在解释器调度的尾调用中会被使用)。我从那时起就没有再关注这个问题(GCC的goto *足够好了(好吧,大部分情况下是这样),我也没有太多理由认为GCC对尾调用的支持有了变化(尽管有一个发行说明提到了sibling calls,我记得我想过应该检查一下)。无论如何,去年我阅读了Xu和Kjolstad的论文“Copy-and-Patch Compilation”,他们使用了尾调用优化。反正,读完那篇论文后,我做了一些测试,看看gcc和clang能否对文章中展示的这类尾调用进行尾调用优化。结果是可以的。Xu和Kjolstad报告称,他们使用了100,000个代码片段,而我们在Gforth中限制在<2000个(用于VM指令、栈缓存的变体、静态超级指令等)。能够处理100,000将允许我们使用需要太多不同代码片段而无法在基于goto *的系统中使用的技术。我们还没有将此实现放入Gforth中,所以祝贺Python社区首先做到了这点。

赞助内容

NordVPN Next-gen Antivirus

本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。

请我喝杯咖啡