将零大小类型实例存储到空指针中

问题描述 投票:0回答:1

根据Rustonomicon

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

另一方面

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

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

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

它在

rustc 1.75.0
下编译并运行良好,但是代码的行为定义良好吗?

一方面,它应该是无操作的,所以可能没有任何问题,另一方面,存在对

null
指针的取消引用,即 UB。

注意:我在这里尝试使用空指针的原因是分配器可能会分配一些非零大小的内存,即使对于我的特定环境中不被接受的 ZST 也是如此。

pointers rust undefined-behavior unsafe
1个回答
0
投票

所提出的问题将导致一个有点令人沮丧的答案,因为情况非常简单:取消引用空指针是总是未定义的行为,句号。 ZST 也不例外。经典的“但它在我的平台上运行良好”是无效的。

您问题的第二部分是更有趣的部分:如果您需要特殊情况的ZST以避免分配,您可以为这些使用“哨兵地址”,分配器可以在第一次使用时分配;请记住,ZST 与其他类型一样具有对齐方式。在这种情况下,ZST 的所有的所有分配都指向相同的内存位置。

但我宁愿建议检查您是否可以使用已经表现出(或可以配置为表现出)此行为的不同系统分配器。

还要记住,平等和同一不是一回事。我可以有两个比较不相等的 ZST values,因为底层相等性检查依赖于内存地址来进行比较。这由 ZST 来完成,因此您的方案可能无法支持这些类型。

© www.soinside.com 2019 - 2024. All rights reserved.