我对 Rust 的别名规则并没有非常牢固的理解(而且据我所知,它们并没有得到很好的定义),但我不明白为什么在 std::slice
文档中 这个代码示例 是正确的。我在此重复这段代码:
let x = &mut [1, 2, 4];
let x_ptr = x.as_mut_ptr();
unsafe {
for i in 0..x.len() {
*x_ptr.offset(i as isize) += 2;
}
}
assert_eq!(x, &[3, 4, 6]);
我在这里看到的问题是,
x
是一个 &mut
引用,编译器可以假定它是唯一的。通过 x_ptr
修改了 x
的内容,然后通过 x
读回来,我认为编译器没有理由认为 x
已经被修改,因为它从未通过唯一存在的 &mut
引用进行修改。那么,我错过了什么?
编译器是否必须假定
*mut T
可能与&mut T
别名,即使通常可以假定&mut T
永远不会别名另一个&mut T
?unsafe
块是否充当某种别名障碍,其中编译器假定其内部的代码可能已修改范围内的任何东西?这个代码示例有问题吗?
如果有某种稳定的规则使这个示例没问题,那么它是什么?它的范围是什么?我应该担心别名假设会破坏 unsafe
Rust 代码中的随机事物吗?
x
和x_ptr
包含相同类型的地址,LLVM必须重新加载x
。 - Stargateur