Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

pointers

rust

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?

like image 497
Pierre-Antoine Avatar asked Dec 20 '19 14:12

Pierre-Antoine


People also ask

What will happen if we will do int * ptr null?

In your case int *ptr = NULL is completely redundant as you could just write int *ptr = a as Vlad has already said, but more generally it is a good idea to initialise pointers to NULL because if for some reason you have an error in your code and you need to debug it, it is a lot easier to debug what is happening to the ...

How do you make a pointer point null?

We can directly assign the pointer variable to 0 to make it null pointer.

How do I know if a pointer is pointing to null?

Test whether the variable is true. A simple if (ptr) tests whether ptr is TRUE. It will return FALSE if ptr is NULL, or if ptr is 0.

Can you use pointers in Rust?

Rust has a number of different smart pointer types in its standard library, but there are two types that are extra-special. Much of Rust's safety comes from compile-time checks, but raw pointers don't have such guarantees, and are unsafe to use. *const T and *mut T are called 'raw pointers' in Rust.


1 Answers

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.

like image 114
trent Avatar answered Sep 28 '22 02:09

trent