Hacker News 中文摘要

RSS订阅

Zig的新bitCast语义与LLVM后端改进 -- Zig's new bitCast semantics and LLVM back end improvements

文章摘要

Zig编程语言2026年开发日志,主要记录了LLVM后端整数类型降级优化和@bitCast语义变更。作者发现直接使用LLVM位整数类型存在优化限制,因为Clang从未生成此类IR导致支持不足,因此进行了改进。

文章总结

好的,作为一名专业的中文编辑,我将对您提供的英文内容进行中文重述,保留核心细节,并删减与文章主题无关的内容。


Zig 编程语言 2026 年开发日志摘要

本文汇总了 Zig 语言主分支在 2026 年的重要更新。

2026年6月25日:@bitCast 新语义与 LLVM 后端改进

作者 Matthew Lugg 完成了一项长期计划:改进 LLVM 后端对整型类型的处理方式。此前,Zig 将任意位宽的整型(如 u4i13)直接映射为 LLVM IR 的位整型,但这并非最优方案,因为 LLVM 对这些类型的内存表示限制过严,且相关代码路径未经充分测试,导致优化缺失甚至编译错误。

核心改动:现在,仅在 SSA 形式下使用位整型,存储到内存时则零扩展或符号扩展至 ABI 标准大小(如 i8i16)。这与 Clang 处理 C 语言 _BitInt(N) 的方式一致。

@bitCast 的重定义:为解决上述改动带来的问题,作者实现了 2024 年提出的语言提案,为 @bitCast 定义了全新的、精确的语义。新语义不再基于“内存字节重解释”,而是基于类型的“逻辑位布局”。例如,u5 有 5 个逻辑位,[2]u5 有 10 个逻辑位(第一个元素的 5 位在前,第二个元素的 5 位在后)。@bitCast 现在就是重解释这些逻辑位。

关键变化: * 跨平台一致性:对于聚合类型(如数组、向量),新语义与目标平台的字节序无关。例如,将 [2]u8 转换为 u16,无论在大端还是小端平台,第一个数组元素始终成为 u16最低 8 位(这与旧语义在小端平台上的行为一致)。 * 更灵活的操作:允许更奇特的转换,例如将 [2]u3 转换为 @Vector(3, u2),或将整数转换为 @Vector(n, u1) 的位向量。 * 其他调整:禁止 @bitCast 与指针向量之间的转换;允许对枚举类型使用 @bitCast

性能提升:作为原始动机的 LLVM 后端整型处理改进,成功恢复了被遗漏的优化。即使 Zig 编译器本身不大量使用任意位宽整型,也观察到了约 5% 的性能提升。

2026年5月30日:ELF 链接器改进

作者 Matthew Lugg 改进了 Zig 0.16.0 中引入的新 ELF 链接器。该链接器目前默认禁用(需 -fnew-linker 启用),但已取得重大进展。

里程碑:新链接器现已能够成功构建包含 LLVM 和 LLD 库的自托管 Zig 编译器。

核心特性:支持快速增量编译。在 x86_64 Linux 上,即使链接外部库和 C 源码,也能实现毫秒级的增量重建。例如,对 Andrew 的俄罗斯方块克隆进行简单修改,重建时间仅约 30 毫秒。Zig 编译器自身的增量重建也仅需 200-300 毫秒。

当前限制:尚不支持为 Zig 代码生成 DWARF 调试信息,这是作者的下一步优先工作。

2026年5月26日:构建系统重构

作者 Andrew Kelley 对 zig build 进行了重大重构,将构建过程拆分为“配置器”和“执行器”两个独立进程。

旧模式build.zig 逻辑与整个构建系统代码被编译成一个臃肿的 Debug 进程。

新模式: 1. build.zig 被编译成一个轻量的 Debug 进程(配置器),负责构建构建图并将其序列化为二进制配置文件。 2. 父进程 zig build 会缓存此配置文件。 3. 同时,父进程异步编译一个 Release 模式的进程(执行器)。 4. 一旦配置文件就绪且执行器编译完成,执行器读取配置文件并执行构建图。执行器只需为每个 zig version 编译一次。

性能提升zig build --help 的执行时间从 150ms 降至 14.3ms,CPU 周期和指令数均减少超过 95%。这是因为现在 zig build 可以复用缓存的配置,而无需每次都重新执行 build.zig 逻辑。

对第三方工具的影响:ZLS 等工具可以直接读取序列化的配置文件,无需维护构建运行器的分支。

主要 API 变更:构建脚本无法再通过 b.args 观察命令行参数,需改用 run_cmd.addPassthruArgs()。这避免了因参数变化而重新编译 build.zig

2026年4月8日:LLVM 后端的增量编译

作者 Matthew Lugg 为 LLVM 后端实现了增量编译支持。虽然无法加速 LLVM 的“Emit Object”阶段,但能显著减少 Zig 编译器自身的耗时。这意味着,如果代码有编译错误(会跳过 LLVM 阶段),错误信息几乎可以即时返回。该功能已合并到主分支,并将包含在 0.16.0 版本中。

2026年3月10日:类型解析重构与语言变更

作者 Matthew Lugg 合并了一个 30,000 行的 PR,对编译器内部的类型解析逻辑进行了彻底重构。

主要改进: * 惰性分析:如果类型从未被初始化,编译器不再分析其字段。这避免了将类型用作命名空间时,意外引入其字段中的 @compileError 等问题。 * 更好的依赖循环错误信息:当出现类型依赖循环时,现在会提供详细的错误信息,明确指出循环的起点和终点。 * 增量编译增强:修复了大量已知错误,特别是几乎消除了“过度分析”问题,使增量编译在许多情况下更快、更稳定。

2026年2月13日:std.Io.Evented 的 io_uring 和 GCD 实现

作者 Andrew Kelley 宣布,std.Io.Evented 的 io_uring(Linux)和 Grand Central Dispatch(macOS)实现已合并。这两个实现都基于用户态栈切换(协程/纤程)。

关键特性:应用程序可以轻松地在不同 I/O 实现间切换,只需更改 main 函数中的初始化代码,而核心业务逻辑(app 函数)无需任何修改。例如,从 std.Io.Threaded 切换到 std.Io.Evented,底层系统调用会从 writev 变为 io_uring_enter

当前状态:标记为实验性,存在一些待解决的问题,如错误处理、性能退化、测试覆盖等。

2026年2月6日:包管理工作流增强

作者 Andrew Kelley 引入了两项改进:

  1. 本地包存储:获取的依赖包现在存储在项目根目录的 zig-pkg 文件夹中(而非 .zig-cache)。这使得用户可以轻松编辑、搜索依赖,或将其包含在可分发的源码包中。同时,全局缓存中会保留一份压缩后的副本,便于跨机器共享,并为未来的 P2P 分发奠定基础。
  2. --fork 标志zig build --fork=[路径] 允许用户用一个本地源码目录覆盖整个依赖树中所有匹配的包。这是一个临时性的、通过 CLI 标志控制的覆盖,非常适合在生态出现问题时,快速使用上游分支进行测试和修复,而无需修改 build.zig.zon

2026年2月3日:绕过 Kernel32.dll

作者 Andrew Kelley 阐述了 Zig 标准库的策略:优先使用 Windows 原生 API (ntdll) 而非 Win32 API (kernel32)。原因是 kernel32 的封装层引入了不必要的堆分配、额外的失败模式、CPU 开销和代码膨胀。

示例 1:获取随机数:官方推荐的 SystemFunction036 函数在 Windows 8 后依赖 bcryptprimitives.dll,该 DLL 的加载可能失败,且首次调用会进行堆分配和运行测试。Zig 通过直接调用 NtOpenFileNtDeviceIoControlFile 来读取 CNG 设备,避免了这些依赖和不确定性。

示例 2:文件读写ReadFileNtReadFile 的封装。NtReadFile 直接返回错误码,而 kernel32 版本则隐藏状态码,需要额外调用 GetLastError。此外,对于异步文件句柄,Zig 使用 APC 例程而非 kernel32 使用的事件,避免了额外的资源分配,并能更好地与任务取消机制集成。

2026年1月31日:zig libc 子项目

作者 Andrew Kelley 介绍了 zig libc 项目的进展。该项目旨在用 Zig 标准库包装函数逐步替换 Zig 仓库中附带的 C 语言源码文件(如 musl、mingw-w64 等)。

进展:已删除约 250 个 C 源文件,剩余 2032 个。每个函数的迁移都减少了 Zig 对第三方 C 项目的依赖,提升了编译速度,并减小了静态链接 libc 的应用程序体积。

优势:导出的 libc 函数现在与 Zig 代码共享编译单元,而非作为独立的静态库。这使得编译器可以在前端进行跨 libc 边界的优化(类似 LTO,但更早进行)。未来,这还可能让用户控制 libc 的 I/O 行为,例如强制其参与 io_uring 事件循环。

评论总结

根据评论内容,主要观点和论据如下:

1. 对深度技术内容的赞赏(评分:None) - 评论1(grayhatter)高度评价这篇开发日志,认为其提供了“深入的技术解释”,是“一股清新的空气”,并讽刺了低质量内容泛滥的现象。 - 关键引用:“the in depth technical explanation is a refreshing breath of fresh air” / “I'm drowning in low effort garbage”

2. 对任意宽度整数的质疑(评分:None) - 评论2(simonask)质疑任意宽度整数的实际价值,认为手动打包/解包能提供更好的代码生成心理模型,尤其对奇数位整数的符号扩展操作表示担忧。 - 关键引用:“Is it actually even really worth it?” / “what kind of code gets generated for sign-extension”

3. 对bitCast语义变更的批评(评分:None) - 评论3(ozgrakkurt)强烈反对bitCast的新语义,认为其破坏了简单低层级的预期行为,建议要么禁止u24转换,要么添加新内置函数而非改变现有行为。 - 关键引用:“This is a huge mistake. You would never expect something like bitCast to do this.” / “Why change something so simple and low level to be complicated and high level?”

4. 对变更的积极评价(评分:None) - 评论4(zamadatix)认为该变更结合现有打包结构逻辑,将极大简化位打包二进制头文件的处理,无需手动调整位操作。 - 关键引用:“This change + the existing packed struct logic will be great for working with bit packed binary headers”

5. 对Zig流行度的困惑(评分:None) - 评论5(epolanski)对Zig在讨论中的高热度表示惊讶,对比C3和Odin等同类语言缺乏关注,猜测是否因Andrew(Zig创始人)更擅长推广。 - 关键引用:“I'm very confused on why C3 or Odin rarely get any attention at all” / “Is Andrew much better at marketing/promoting the language?”

6. 对格式的无关评论(评分:None) - 评论6(QuaternionsBhop)仅询问文中大量使用em-dash是否为内部玩笑,未涉及实质观点。