When is it appropriate to mark a function as unsafe
versus just using an unsafe
block? I saw this function while reading another answer:
unsafe fn as_u8_slice(xs: &[i32]) -> &[u8] {
std::slice::from_raw_parts(v.as_ptr() as *const u8,
v.len() * std::mem::size_of::<i32>())
}
I probably would have written the function as:
fn as_u8_slice(xs: &[i32]) -> &[u8] {
unsafe {
std::slice::from_raw_parts(v.as_ptr() as *const u8,
v.len() * std::mem::size_of::<i32>())
}
}
That is, I feel like calling the function is safe in all cases, but what the function does internally cannot be verified by the compiler. However, I don't have any rules for when it is appropriate to use one or the other.
unsafe
is designed as a local mechanism to step around the type system when the compiler is unable to prove safety. If the behaviour encapsulated by theunsafe
is safe, i.e. there is no way to call it that will cause memory unsafety, then there is no need to label the overall function unsafe. The user doesn't need to care if the function internals are implemented entirely with safe code or withunsafe
, as long as the exposed interface is correct.Mark a function as
unsafe
iff the function's safety depends on its parameters or on global state. If the function is safe regardless of arguments and global state, don't mark it asunsafe
. Whether you consider a function that usesunsafe
internally safe is the same as whether you consider a C program safe.