How do I decide when to mark a function as unsafe?

2019-02-22 06:10发布

问题:

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.

回答1:

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.



回答2:

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.



标签: rust