内容提要
Rust修复了与C在x86-32和x86-64架构上对齐128位整数的不一致问题,对大多数用户没有影响。修复可能提高运行时性能,但可能增加内存使用。
延伸解读
对齐不一致的根源与影响
Rust 的 i128 和 u128 在 x86-32 和 x86-64 上曾与 C 语言对齐不一致,Rust 对齐为 8 字节,而 C 的 __int128 对齐为 16 字节。这种不一致源于 LLVM 将 i128 对齐硬编码为 8 字节,而 Clang 通过手动调整规避了问题。对齐不一致会导致 Rust 与 C 之间共享包含 128 位整数的数据时出现错误,尤其是在 FFI 场景中。
修复带来的性能与内存权衡
将 i128/u128 的对齐从 8 字节改为 16 字节后,由于更符合 ABI 的推荐,可能提升运行时性能,尤其是在大量使用 128 位整数的代码中。但更高的对齐也可能导致复合类型在内存中产生更多填充,从而增加内存占用。文章提到,为了避免内存占用增加,部分性能收益被牺牲。
兼容性矩阵与升级建议
从 Rust 1.78 开始,使用捆绑 LLVM 18 的 Rust 与任何版本的 GCC 以及 Clang 18 及以上完全兼容。Rust 1.77 配合 LLVM 18 也完全兼容。若使用更早的 LLVM,则可能存在存储兼容但调用约定错误的问题。Rust 1.77 之前与 GCC/Clang 完全不兼容。建议在 FFI 中使用 128 位整数时,确保编译器版本满足兼容性要求。
对开发者的实际影响
大多数用户不会注意到这些变化,除非他们假设 i128/u128 的对齐方式,或者忽略 improper_ctypes 警告并在 FFI 中使用这些类型。从 Rust 1.77 开始,在 FFI 中试验 128 位整数变得相对安全,但完全兼容性需等到 1.78 的 LLVM 更新。目前相关 lint 仍在讨论是否移除,以避免使用旧版 LLVM 的用户遇到静默破坏。
Q&A
Rust 1.77和1.78版本中对齐128位整数的变更是什么?
Rust修复了与C在x86-32和x86-64架构上对齐128位整数的不一致问题。
这些变更对用户有什么影响?
大多数用户不会注意到这些变化,除非假设i128/u128的对齐或在FFI中使用这些类型时忽略不当的ctypes警告。
修复128位整数对齐问题的原因是什么?
Rust与C在128位整数的对齐上存在不一致,导致数据共享问题,修复后可提高运行时性能。
Rust 1.78版本与其他编译器的兼容性如何?
Rust 1.78及以上版本与GCC和Clang 18及以上版本完全兼容。
修复对齐问题后,内存使用情况会有什么变化?
修复可能提高运行时性能,但可能增加内存使用。
Rust的i128和u128类型在对齐上曾与C不一致的原因是什么?
这是因为LLVM在处理128位整数时对其对齐进行了错误的硬编码,导致Rust的对齐方式不正确。