4 ms·
> Is there such a boundary? How do you know a function doesn't call unsafe code without looking at every function called in it, and every function those functio
by cesarb 2y ago
> Is there such a boundary? How do you know a function doesn't call unsafe code without looking at every function called in it, and every function those functions call, and so on?
Yes, there is a boundary, and usually it's either the function itself, or all methods of an object. For instance, a function I wrote recently goes somewhat like this:
fn read_unaligned_u64_from_byte_slice(src: &[u8]) -> u64 {
assert_eq!(src.len(), size_of::<u64>());
unsafe { std::ptr::read_unaligned(src.as_ptr().cast::<u64>()) }
}
The read_unaligned function (https://doc.rust-lang.org/std/ptr/fn.read_unaligned.html https://doc.rust-lang.org/std/ptr/fn.read_unaligned.html) has two preconditions which have to be checked manually. When doing so, you'll notice that the "src" argument must have at least 8 bytes for these preconditions to be met; the "assert_eq!()" call before that unsafe block ensures that (it will safely panic unless the "src" slice has exactly 8 bytes). That is, my "read_unaligned_u64_from_byte_slice" function is safe, even though it calls unsafe code; the function is the boundary between safe and unsafe code. No callers of that function have to worry that it calls unsafe code in its implementation.