按每Rustonomicon

Rust在很大程度上理解,任何产生或存储 ZST可以简化为无操作

另一方面,

请注意,对ZST(包括空切片)的引用,就像所有 其他引用,必须是非空的,并适当地对齐.解引用 指向ZST的空指针或未对齐指针是未定义行为,就像 对于任何其他类型.

这两段话对我来说似乎有点矛盾.请考虑以下示例:

fn main() {
    let null_ptr = ptr::null_mut::<()>();
    unsafe { *null_ptr = () }
}

它在rustc 1.75.0以下编译和运行得很好,但是代码的行为是否定义良好?

一方面它应该是无操作的,所以可能没有任何问题,另一方面有null个指针的取消引用,这是UB.

Note:我在这里try 使用空指针的原因是,分配器可能会为ZST分配一些非零大小的内存,这在我的特定环境中是不被接受的.

推荐答案

如上所述,这个问题将导致一个有点令人沮丧的答案,因为情况很简单:取消引用空指针是always个未定义的行为,句号.ZST也不例外.classic 的"但它在我的平台上运行得很好"是无效的.

您的问题的第二部分更有趣:如果您将need设置为特殊情况下的ZST以避免分配,您可能需要为这些类型使用"前哨地址",分配器可以在第一次使用时分配这些地址;请记住,ZST和其他类型一样具有对齐方式.在该场景中,ZST的所有values的所有分配指向相同的存储器位置.

然而,我更愿意建议您判断是否可以使用已经表现出(或可以配置为表现出)这种行为的不同系统分配器.

还要记住,平等和身份不是一回事.我可以有两个values的ZST进行不相等的比较,因为底层的相等判断依赖于内存地址来进行比较.这取决于ZST,因此您的方案可能无法支持这些类型.

Rust相关问答推荐

trait 中self 的显式生命周期似乎导致E0499无法在循环中多次borrow * emits 器作为可变的

Rust,polars CSV:有没有一种方法可以从impll BufRead(或任何字节迭代器)中读取CSV?

有条件默认实现

基于对vec值的引用从该值中删除该值

空字符串转换为Box字符串时是否分配?<>

当为a Self:IntoIterator设置trait bind `时,获取`a T `不是迭代器"&'"<'>&'

替换可变引用中的字符串会泄漏内存吗?

使用Rust WASM读取文件

如何将生存期参数添加到框<>;具有dyn类型别名

可选包装枚举的反序列化

仅在使用 &mut 或线程时borrow 的数据在闭包之外转义?

pyO3 和 Panics

从 HashMap>, _> 中删除的生命周期问题

Rust 中的方法调用有什么区别?

哪些特征通过 `Deref` 而哪些不通过?

使用 rust 在 google cloud run (docker) 中访问环境变量的适当方法

在 RefCell 上borrow

如何从 many0 传播 Nom 失败上下文?

Rust 为什么 (u32, u32) 的枚举变体的大小小于 (u64)?

加入动态数量的期货