在《Learning Rust With Entirely Too Many Linked Lists》一文中,作者定义了如下链表结构:
pub struct List<T> {
head: Link<T>,
tail: *mut Node<T>,
}
type Link<T> = Option<Box<Node<T>>>;
struct Node<T> {
elem: T,
next: Link<T>,
}
作者认为这个结构不好,混用 Box 和 raw pointer 容易导致 UB。作者认为 Box 是安全指针,引入了一些 raw pointer 根本不会遵守的约束。作者思路是全部用 raw pointer。
我对作者思路的理解是: 1.通过解引用 Box 来修改变量是 safe 的,但是通过解引用 raw pointer 是 unsafe 的。所以当一个变量有两个指针 raw pointer 和 Box 的时候,容易通过解引用 Box (这是 safe 的)直接把变量修改了,而忘记了还有 raw pointer 这个 unsafe 的声明了; 2.如果全部用 raw pointer 或者用 NonNull 来替换 Box,那么不管何时修改变量都要限制在 unsafe 中,开发者就会注意变量的读写逻辑(例如遵守 reborrow 规则),避免 UB;
请教下大家的理解,如果能给出例子最好了,谢谢。:-)
Ext Link: https://rust-unofficial.github.io/too-many-lists/fifth-stacked-borrows.html
1
共 3 条评论, 1 页
评论区
写评论基本思路应该是对的。
作者的实践方案是:
我在写完 unsafe_queue 后,改写
Link<T>
从Box<Node<T>>
到NonNull<Node<T>>
两种数据结构设定,有五个操作不同,但可以抽象出一个 trait 来屏蔽差异
谢谢大佬指路,之前没怎么读过 reference,里面内容还挺多的。:-)
--
👇
Bai-Jinlin: 指的应该是编译器noalias这方面东西 https://doc.rust-lang.org/reference/behavior-considered-undefined.html
Box本身是noalias,不允许其他引用访问或者修改Box指向的内存,你给的代码假如head和tail引用了一个Node就违反了这个保证,在rust里就是ub。
指的应该是编译器noalias这方面东西 https://doc.rust-lang.org/reference/behavior-considered-undefined.html
Box本身是noalias,不允许其他引用访问或者修改Box指向的内存,你给的代码假如head和tail引用了一个Node就违反了这个保证,在rust里就是ub。