Why is `std::ptr::null` not usable with unsized types?

好久不见. 提交于 2020-05-14 19:16:12

问题


As I understand, the standard (only?) way to make a null pointer in Rust is std::ptr::null.

However, that function is declared as follows.

pub const fn null<T>() -> *const T

In this declaration, T is implicitly assumed to have fixed size (otherwise, it would be T: ?Sized). As a consequence, it is impossible to use this function with *const str or *const [u32] for example. test it in the playground

Is there a good reason for excluding unsized types? What's wrong with wanting to create a null *const str?


回答1:


A pointer to an unsized type is a fat pointer with two components: the pointer and the type metadata (a length for slices, and a vtable pointer for trait objects; in the future, Rust may allow other kinds of metadata). null only implies a value for the pointer part; there's no obvious choice for the other value. (You might think 0 is obvious for the length of a null slice pointer, and I can see the argument, but if the pointer is null it hardly matters how many things are there; you can't dereference it anyway, so making the size 0 is not necessary to ensure safety.)

There is no way to create a null pointer to a trait object, but as of Rust 1.42, you can use ptr::slice_from_raw_parts to create a null pointer to a slice. Let's suppose the length of the slice is 0:

use std::ptr;
fn main() {
    let p: *const [u32] = ptr::slice_from_raw_parts(ptr::null(), 0);
    println!("{:?}", p);
}

There is no equivalent function for str, but you could make one by creating a null *const [u8] and casting it with as.

This function (or the related slice_from_raw_parts_mut) is the only way to soundly create a null pointer to a slice. The usual way to get a raw pointer is by casting a reference, but references may never be null.



来源:https://stackoverflow.com/questions/59426821/why-is-stdptrnull-not-usable-with-unsized-types

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!