Reputation: 431679
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.
Upvotes: 9
Views: 2202
Reputation:
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 as unsafe
. Whether you consider a function that uses unsafe
internally safe is the same as whether you consider a C program safe.
Upvotes: 17
Reputation: 102216
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 the unsafe
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 with unsafe
, as long as the exposed interface is correct.
Upvotes: 5