为什么通过指向移动变量的指针写入在 Rust 中没有被确定为 UB?

Why writing through a pointer to a moved variable has not been decided as UB in Rust?

我正在调查阻止 Rust 编译器优化 . I found this comment rust-lang 中提醒我的问题的可能原因。

We must not optimize away storage of locals that are mutably borrowed, because as @matthewjasper notes in #61430, it isn't decided that the following is UB:

let mut x = String::new();
let p = &mut x as *mut String;
let y = x;
p.write(String::new());

我以为 x 的生命周期在移动到 y 时就结束了。 p.write() 通过时悬空。但为什么这不被定为UB?

在同一个线程中,更进一步,cramertjother comment 我认为可以稍微解释一下这个问题。其他评论中举例说明的代码是:

let mut x = String::new();
let addr_x: *const String = reference_to_pointer(&x);
drop(x);
ptr::write(addr_x as *mut String, String::new());

此代码段的基本思想是能够 drop 一个局部值到 运行 其析构函数并重用其内存分配来存储新值。这是一个模式,有些人认为它可能有用,但其他人认为它应该是UB。

请记住,drop() 无论如何都不是一个特殊函数,它只是将 x 移动到它自己的范围内并立即完成,因此它或多或少等同于您的原始代码。您甚至可以使用 forget() 或将值推送到容器中,示例仍然有效。

请注意,如果您使用分配的动态内存(这就是 Vec 在幕后所做的),这个习惯用法实际上是有效的。这里的问题是它是否对堆栈分配的自动内存也有效。