Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should we use Option or ptr::null to represent a null pointer in Rust?

Tags:

idioms

null

rust

The standard library's linked-list Node uses the Option type:

struct Node<T> {
    next: Option<NonNull<Node<T>>>,
    prev: Option<NonNull<Node<T>>>,
    element: T,
}

and creates a node with this code:

Node {
    next: None,
    prev: None,
    element,
}

The implementation of LeafNode of BTree, the standard library uses a raw pointer for the parent node:

struct LeafNode<K, V> {
    parent: *const InternalNode<K, V>,
    parent_idx: MaybeUninit<u16>,
    len: u16,
    keys: MaybeUninit<[K; CAPACITY]>,
    vals: MaybeUninit<[V; CAPACITY]>,
}

and creates new leaf nodes by setting parent to ptr::null:

LeafNode {
    keys: MaybeUninit::uninitialized(),
    vals: MaybeUninit::uninitialized(),
    parent: ptr::null(),
    parent_idx: MaybeUninit::uninitialized(),
    len: 0
}

We can use nullptr to implement the above code in C++, so what's the difference between Option and std::ptr::null() to represent a null pointer? What's the recommended way to represent a null pointer?

like image 268
McGrady Avatar asked Jan 15 '19 08:01

McGrady


People also ask

How do you use null in Rust?

In Rust, the idea of null is modelled with Option . You give a field the type Option<TcpStream> to indicate that it might not be there ( None ), or be a valid value ( Some(TcpStream) ). Show activity on this post. You will need to change your type to Option<TCPStream> if you would like to keep this call pattern.

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 ...

Is there pointer 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.


1 Answers

In general, I'd recommend using NonNull<T> over *const T or *mut T, using Option as appropriate to identify when the pointer may be null.

The reason is two-fold:

  1. Whether null is a valid value, or not, is documented and enforced when using NonNull.
  2. *const T and *mut T are essentially interchangeable, and indeed can be cast to one another, so that const or mut may provide a false sense of safety.

The implementation of BTree may simply not have been ported over to NonNull, which is relatively recent -- it was stabilized only in 1.25.

like image 68
Matthieu M. Avatar answered Oct 29 '22 21:10

Matthieu M.