1.77和1.78版本中`u128`/`i128`布局的变更

1.77和1.78版本中`u128`/`i128`布局的变更

💡 原文英文,约1800词,阅读约需7分钟。
📝

内容提要

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的对齐方式不正确。

🏷️

标签

➡️

继续阅读