Unsafe Rust. Sounds contradicting to what we know about Rust as Rust is one of the safest and memory-efficient languages. It does not have a garbage collector because it does not need one. Rust has wonderful borrowing and ownership rules that take care of all the memory safety issues. It is one of the leading languages. More than 9 companies including Dropbox, Coursera, Figma, npm, Microsoft, Cloudflare, Facebook, Amazon and Discord use Rust for one or the other things. But then what are Unsafe Rust and Raw pointers. Is it something to worry about or is it something dangerous? We will see and learn about unsafe Rust in this and upcoming blogs.
Introduction
We all know that Rust is blazing fast and memory-efficient with no runtime or garbage collector. But sometimes the Rust compiler does not let you run your code when it is unsure about its memory safety or does not have enough information to be confident. The Rust compiler believes in rejecting some valid code rather than accepting a code that could cause a memory leak.
If we are sure that the code we have written is valid and will not cause any problems, we can use a very powerful feature of Rust that is Unsafe Rust. But if we use Unsafe Rust, we are completely responsible for any future memory-related issue, such as dereferencing a null pointer.
How to use unsafe?
Let us understand how can we use the ultimate power of unsafe Rust. Keep one thing in mind, when I say the ultimate power of unsafe Rust, it does not mean that you can do anything in an unsafe block. It does not disable the borrow checker or any other safety feature of Rust. The things that you can do in an unsafe block are –
- Dereference a raw pointer
- Call an unsafe function or method
- Access or modify a mutable static variable
- Implement an unsafe trait
- Access fields of unions
These are the points that will not be checked when using unsafe Rust.
We will be seeing all these points that are valid in unsafe Rust in upcoming blogs. But in this blog, I will talk about the first point. It is about dereferencing raw pointers. Till now we know about references and smart pointers, this is something new. Let us first get a short intro about raw pointers.
Raw pointers
In unsafe Rust, we have two new pointers other than references and smart pointers and they are called raw pointers. Raw pointers can be mutable and immutable like references. We can define raw pointers by using *const T
and *mut T
.
An immutable raw pointer denoted by *const T,
can not be directly assigned to after dereferenced. The main point to remember about raw pointers is that we can have mutable and immutable raw pointers to the same location at the same time. This is something different from references.
we can define raw pointers like this – let ptr = &num as *const u32;
This creates a raw pointer to the memory location of the num variable which is of u32 type.
Dereference a raw pointer
Now that we have an idea about Raw pointers, we can now see where can we use unsafe Rust. Let us see an example to find out.
Look at the code given below
let mut value = 10;
let immutable_raw_pointer = &value as *const i32;
let mutable_raw_pointer = &mut value as *mut i32;
If we look closely there are immutable and mutable pointers to the same memory location. If we try to dereference these we get a compilation error.
Try to run the following lines of code.
print!("value is: {}", *immutable_raw_pointer);
print!("value is: {}", *mutable_raw_pointer);
You will see the error message given below.
If you observe the error messages it says that
"dereference of raw pointer is unsafe and requires unsafe function or block"
The Rust compiler know that this code can cause some memory issues.
Resolve the error
We resolve the error by using an unsafe block assuring the compiler that we take the responsibility for any issue. We just put the print commands where the dereferencing of raw pointers occurs to let the compiler know that don’t worry about these commands.
unsafe{
print!("value is: {}", *immutable_raw_pointer);
print!("value is: {}", *mutable_raw_pointer);
}
Now the code compiles successfully. The unsafe block prevents the compiler from checking the contents of the block for the points which I told earlier and dereferencing a raw pointer is one of them. So the code compiles without any issue.
This was all about Raw pointers and Unsafe Rust. We will learn more about Unsafe Rust in upcoming blogs. So stay tuned.
If you want to read more content like this? Subscribe to Rust Times Newsletter and receive insights and latest updates, bi-weekly, straight into your inbox. Subscribe to Rust Times Newsletter: https://bit.ly/2Vdlld7.




1 thought on “Raw Pointers in Unsafe Rust are quite powerful4 min read”
Comments are closed.