主要观点:Rust 与 C 的显著区别在于要求所有值都有定义的大小,这使得运行时边界检查和高级静态分析工具成为可能。对于动态大小类型(DST),Rust 使用厚指针实现该要求,每个指向动态大小值的指针是一个(地址,大小)元组。厚指针使用方便但有性能缺陷,会占用两倍寄存器空间。此页面是RFC 3536的补充,提议 Rust 应支持指向 DST 的薄指针。
关键信息:
C 中的动态大小类型:
- 数组和字符串:C 中最简单的 DST 是动态分配的数组,其大小需作为参数传递。NUL 终止的字符串大小虽可计算但不固定,易导致字符串操作代码难以理解,现代系统编程语言避免使用。GLib 有类似的厚指针 idiom 用于动态大小值。
- 灵活数组成员:在处理低级协议时常用,通过在结构末尾放置占位数组实现,C99 将其纳入语言。Linux 内核已逐渐采用 C99 灵活数组成员。
- 指向不完整类型的指针:C 允许声明未定义的结构,形成不完整类型的指针,其指针可不指向实际对象,C 程序员常将其用于隐藏实现细节。
Rust 中的动态大小类型:
- !Sized 薄指针提案:基本目标是性能优化,将动态大小值视为有很多数组成员的联合,通过#[repr(thin_unsized)]属性标记 DST 类型为薄指针类型,并实现 ThinUnsized 特质来报告大小。薄指针 DST 在结构的最后字段时行为类似,且与 Mutex 和 Box 交互时,其报告的大小在对象的整个生命周期中不能改变。
重要细节:
- C 中许多现存库假设 size_t 和 uintptr_t 等价,代码中常使用指针大小的无符号整数。
- Rust 中通过core::mem模块在运行时检查值的大小和对齐。
- Rust 编译器已在自身代码中使用 extern 类型实现灵活数组成员。
- 薄指针提案中对 Packet 类型的处理及相关安全特性等。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。