Claude 编写的 C 语言编译器对比 GCC
Hacker News 摘要原标题:Claude’s C Compiler vs. GCC
Anthropic 最近发布了一篇博客,介绍了一个完全由 Claude 编写的 C 语言编译器,简称 CCC。这个编译器 100% 的代码由 Claude Opus 4.6 生成,人类仅通过编写测试用例来引导过程。作者对此进行了详细测试,并将其与行业标准 GCC 进行了对比。
CCC 的基本情况
CCC 完全使用 Rust 编写,目标架构包括 x86-64、i686、AArch64 和 RISC-V 64。它的前端、基于 SSA 的中间表示(IR)、优化器、代码生成器、窥孔优化器、汇编器、链接器以及 DWARF 调试信息生成全部从零实现,没有使用任何特定于编译器的第三方依赖。
编译器的工作阶段
编译一个 C 程序通常涉及四个阶段:
1. 预处理器:处理 include 和 define 等指令。
2. 编译器:将源代码翻译成汇编语言,这是最核心的步骤,涉及类型检查、优化和寄存器分配。
3. 汇编器:将汇编语言转换为机器码(目标文件)。
4. 链接器:将多个目标文件合并为单个可执行文件。
测试环境与方法
作者在 Proxmox 虚拟机上对比了 GCC 14.2.0 和 CCC。测试对象选择了 Linux 内核 6.9 和 SQLite 3.46.0。
• Linux 内核:用于测试编译器的规模处理能力和兼容性。
• SQLite:它是标准的 C 语言实现,且可以合并为单个文件,非常适合测试正确性和运行性能。
Linux 内核编译结果
CCC 的表现令人印象深刻,它成功编译了内核中所有的 2844 个 C 源文件,没有产生任何编译器错误。然而,构建最终在链接阶段失败了,产生了超过 4 万个未定义引用错误。
• 原因分析:这是链接器的漏洞。CCC 产生的重定位条目和符号表格式不正确,无法满足内核复杂的链接脚本要求。
• 资源消耗:CCC 的内存峰值占用是 GCC 的 2.3 倍。
SQLite 基准测试结果
在正确性方面,CCC 编译的 SQLite 通过了所有崩溃和边缘情况测试,查询结果也完全正确。但在性能和生成物体积上,差距巨大:
• 编译时间:在不开启优化的 O0 模式下,CCC 比 GCC 慢约 25%。
• 二进制体积:CCC 生成的可执行文件大小是 GCC 的 2.7 到 3.0 倍。
• 运行速度:这是最大的弱点。CCC 编译的程序运行速度比 GCC 慢 737 倍到 15.8 万倍不等。
为什么 CCC 编译的代码这么慢?
作者分析了几个核心原因:
1. 寄存器溢出:这是性能低下的首要原因。现代 CPU 寄存器数量有限,好的编译器会尽量让变量留在寄存器中。而 CCC 的寄存器分配能力很差,几乎将所有变量都溢出到内存栈中。在 SQLite 的执行引擎中,原本在寄存器内完成的操作,被 CCC 变成了大量的内存读写。
2. 优化层级形同虚设:虽然 CCC 接受 O2 或 O3 标志,但实际上它对所有级别都运行相同的 15 个优化路径。这意味着它的 O2 输出与 O0 字节完全一致。
3. 代码膨胀:生成的指令数量过多,导致 CPU 缓存命中率下降。
4. 子查询性能爆炸:对于简单的插入操作,CCC 只慢了 1.7 倍。但对于涉及嵌套循环的复杂查询,由于寄存器分配不当带来的开销会在数十亿次迭代中累积,导致速度慢了 15.8 万倍。
兼容性与调试问题
CCC 的预处理器存在路径搜索问题。在 GitHub 上的第一个 Issue 就是“Hello World 无法编译”,原因是它找不到系统自带的 stddef.h 等头文件。此外,CCC 生成的二进制文件缺乏函数符号,且帧指针链损坏,导致无法使用 GDB 进行调试或使用工具进行性能分析。
结论
作为一项技术成就,CCC 是非凡的。它证明了 AI 可以构建极其复杂的软件系统,并且在逻辑正确性上达到了很高水平。
• 成功之处:实现了高度的正确性和稳定性,能够处理数百万行复杂的 C 代码。
• 短板:生成的机器码效率极低,且在底层系统连接(链接器)和调试支持上仍有欠缺。
目前,CCC 更多地是一个展示 AI 能力的实验性项目。对于实际生产环境,GCC 和 Clang 仍然是唯一的选择。作者已将所有的测试脚本、结果和分析图表发布在 GitHub 仓库中供大家查阅。