Linting unsafe code blocks

In some situations, especially if we are using extremely low-level programming, sometimes used for high-performance computing, we will need to perform some pointer arithmetics or even Single Instruction, Multiple Data (SIMD) intrinsics that will require unsafe scopes. This might be the case in some specific functions or pieces of code, but in general, we should avoid unsafe scopes.

A rule of thumb is this: if you are not working on performance-critical code, do not use them. If you are, use them very carefully and only in places where there is no other option to improve performance. This means that usually intrinsic code can be wrapped in one module or function.

To make sure nobody uses unsafe code outside the scope where we want it to be shown, we can lint all unsafe scopes by using the unsafe_code lint. Let's see it as an example:

#![warn(unsafe_code)]

fn main() {
let test = vec![1, 2, 3];
println!("{}", unsafe { test.get_unchecked(2) });
}

If you remember from Chapter 1, Common Performance Pitfalls, the get_unchecked() function in a slice will get the element at the given index without checking the bounds of the slice, making it go faster. This also means that if the index is out of bounds, you could get from a memory leak to a segmentation fault.

In this example, when compiling this piece of code, a warning will tell us that we are using unsafe code. We can allow it for this particular function if it's 100% required, or we can change the code. An example fixing the issue above while still using unsafe code can be seen here:

#![deny(unsafe_code)]

fn main() {
let test = vec![1, 2, 3];
println!("{}", get_second(&test));
}

#[allow(unsafe_code)]
fn get_second(slice: &[i32]) -> i32 {
*unsafe { slice.get_unchecked(1) }
}

In this example, the crate won't compile if we add an unsafe scope outside the get_second() function. In any case, this function is not safe, as it will not check any bounds of the slice being sent to it; we should probably add an assert!(), or at least a debug_assert!(), to the length of the slice at the beginning of the function.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.188.218.157