You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将ZST实例存入空指针的Rust代码行为是否符合定义?

解引用指向ZST的空指针是否属于未定义行为?

根据《Rustonomicon》中的描述:

Rust通常认为任何生成或存储零大小类型(ZST)的操作都可简化为无操作(no-op)

但同时又有明确规则:

注意,指向ZST的引用(包括空切片)与其他所有引用一样,必须非空且对齐正确。解引用空指针或未对齐指针指向ZST属于未定义行为(UB),与其他类型一致。

这两段规则看似矛盾,比如下面这段代码在rustc 1.75.0下可以正常编译运行,但它的行为是否符合Rust语言定义?

use std::ptr;

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

结论:这段代码属于未定义行为

虽然存储ZST的操作会被编译器优化为无操作,但Rust的语言规范优先于编译器优化细节。解引用指针的前提条件是指针必须合法——即非空且满足对齐要求,这个规则对所有类型都适用,包括ZST。

编译器会基于“解引用的指针都是合法的”这一假设进行优化,哪怕实际操作最终被简化为no-op,违反前提的代码依然属于UB。当前版本编译器可能不会触发错误,但未来版本可能因为这个假设生成导致程序崩溃或异常的代码。

替代方案

如果你的需求是避免分配器为ZST分配非零大小的内存,可以使用NonNull::dangling()来获取一个合法的、非空且对齐的指针,专门用于ZST场景:

use std::ptr::NonNull;

fn main() {
    let dangling_ptr = NonNull::<()>::dangling();
    unsafe { *dangling_ptr.as_mut() = () }
}

该指针不会指向任何实际内存,但满足Rust对指针合法性的要求,同时存储ZST的操作依然会被优化为无操作,完全符合你的需求。

内容的提问来源于stack exchange,提问作者Some Name

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 22:11:08