3 ms·
Unsafety is contagious, the whole point of "unsafe {}" is to create a well defined interface between code that can rely on safety guarantees enforced by the com
by simias 6y ago
Unsafety is contagious, the whole point of "unsafe {}" is to create a well defined interface between code that can rely on safety guarantees enforced by the compiler and code that needs to be manually checked by the developer.
Safe bindings to unsafe code need to enforce the invariants to make the calls safe, otherwise they are not safe.
Consider this code:
fn int_to_string(e: &mut u32) -> &mut String {
unsafe {
&mut*(e as *mut u32 as *mut String)
}
}
fn main() {
let mut i = 42u32;
let s = int_to_string(&mut i);
s.push_str("Ayyy");
println!("{}", s);
}
This int_to_string function is marked safe and can be called from main without
any unsafe block, yet if you run this code it will probably segfault. Or maybe
it'll format your hard drive, who knows. Because int_to_string is clearly unsound
and is broken.
If you just start tagging random, potentially unsound interfaces as safe, what's even the
point?
And if you agree that the code in this example is bad and "int_to_string" should definitely not be considered safe, why would that change if I rewrote it to make "int_to_string" a C++ function called through FFI instead?