goc 专栏
goc 专栏
goc 是一个用 Go 写的 C 编译器,也带一个自研汇编器 goa。它做的事有点极端:
编译 C 代码,产物既不依赖 gcc,也不依赖 libc。
Windows 上产物是 PE32+,只导入 kernel32 / user32 / gdi32 这类系统 DLL;Linux 上产物是静态 ELF64,一条动态链接都没有,只走 syscall。两头都没有 msvcrt,也没有 glibc。
源码在 GitHub:yafengabc/goc(MIT 许可,公开仓库,已发布 v0.1.1)。
这个专栏写什么
这个专栏分四块:
| 篇章 | 内容 |
|---|---|
| 项目介绍 | goc 是什么、为什么这么做、架构怎么分的、和gcc 差在哪 |
| 上手教程 | 从装工具链到写出第一个程序,含Windows GUI 和 Linux 双目标 |
| 体积实测 | 同一份源码,goc / goc+LLVM 后端 / gcc 三方对比,全部自己跑出来的数字 |
| 项目状态 | 已经能做什么、还不能做什么、正在进行什么,附一份测试失败怎么读的经验 |
另有一份开发笔记(content/goc/devnotes/),记录 bug 排查与修复的完整过程——不走弯路的那部分不进教程。
为什么值得写
goc 最有意思的地方不是"又写了个编译器"——那没什么新鲜的。而是它把取舍做得非常明白:
- 不要 gcc:既然是 Go 写的编译器,那就纯到底,产物里不会出现任何 C 工具链的痕迹。
- 不要 libc:那
printf怎么办?答案是把它当成一个真正的库函数写在 C 里,按需发射——只调用putchar的程序不会背上printf的 512字节输出缓冲。 - 不要假设 CPU 会变好:验证环节直接上QEMU(Unicorn),因为手写解释器只能证明"代码生成器和我的理解一致",证明不了程序真的对。
这三条决定了 goc 的整个形态。后面几篇会逐一展开。
现状速览
写这个专栏时的实测状态(2026-10-06):
- 仓库 176 次提交,最新 tag
v0.1.1(提交数会随迭代变化,以仓库为准) run_tests.sh在 Windows 11 + MSYS2 下跑出 pass=253 fail=0- 85 个C 示例,81 份 golden
- 默认后端回归基线
gocregress pass=490 fail=0(82 example × 6 腿,2026-10-07 实测) - C99主体 + C11 类型系统 + C23 实用子集全部落地
_BitInt(N)已实现,10 万位π 二分算法 100,011 位对拍 Python 大整数通过- 编译器本身便携:
goc.exe4.65 MB 单文件(只导入 kernel32);gocl.exe+libLLVM.dll两个文件,拷到空目录、清空PATH也能编 C
阅读顺序
- 第0 章:为什么再写一个 C 编译器 —— 项目介绍与设计取舍(含"交付物只有一个文件"的便携性实测)
- 第 1 章:5 分钟跑起来 —— 装工具链,编译第一个程序
- 第 2 章:写第一个 Windows GUI 程序 —— 用 MessageBox 弹个框
- 第 3 章:体积实测 —— goc / LLVM 后端 / gcc 对比
- 第 4 章:项目状态与 roadmap —— 能做什么,不能做什么
开发笔记
| 笔记 | 内容 |
|---|---|
| 变参窄整型丢符号性 | gocl 把经变参传的 32 位整型符号性丢掉:从误诊为"有符号除法"到定位为"8 字节参数槽没填满"的完整排查过程 |
| 把 gocld 变成真正的链接器 | 让 goc -c 产出可重定位目标文件,gocld 成为可独立运行的链接器:字符串表 NUL、Elf64_Sym 漏 st_other、section 索引 1-based 等字节级坑 |
| 让 gocld 链接 .rsrc 资源节 | 让 gocld 读入/合并/写出 PE 的 .rsrc:OffsetToData 文件偏移陷阱、ENTRY 高位标志、rd32 符号扩展等 |
| gocl(LLVM 后端)踩过的坑 | libLLVM 的 FFI 约定、LLVM IR 畸形输出、COFF 重定位丢 addend 导致控制台全哑、printf 特化的架构缺口、PE 段级文件对齐、TLS 访问被当成 extern 全局、AT&T 前端操作数方向——共 64 条,每条含源码位置与实测 |
| gocl 通用化与 Linux ELF 填坑 | 从「连 goclib 都编不过」到「ls 在 Windows PE 与 Linux ELF 逐字节一致」的 13 个坑:goc 宏、syscall 桩第 4 参、brk identity 宏段错误、整数提升、跨平台一致性 |
⚠️ 说明:本专栏所有体积、测试数字均为在作者机器(Windows 11 + MSYS2)实测所得,标注了日期。goc 迭代很快,数字会变——但结论和方法相对稳定。