|
> I was under the (possibly wrong) impression that you have the binary of either safe or unsafe No, that completely misunderstands what the unsafe keyword is for. Rust has some very strict rules to preserve safety and everybody has to obey those rules. However, in safe Rust you don't need to think about that - or even know what the rules are exactly - because the safe Rust subset always obeys the rules. In unsafe Rust you are responsible for upholding all the rules, which means you need to properly understand what the rules are and be careful to do your job properly, the same responsibility you have in every single line of C++. Another way to think about it is that "unsafe" means "trust me, this is OK". You may find that a more helpful way to understand what unsafe blocks do, but the reason I don't prefer it is that people (including Herb and Bjarne) seem to imagine we're just "switching off" the safety rules, and that's not what happens in any way, semantically, syntactically or de facto. Suppose I have an group of three integers (indexes start at zero) let group = [1, 2, 3]; println!("{}", group[5]); -- that won't work, Rust will reject that because it's a bounds miss†. But if we replace that println! with println!("{}", unsafe { group[5] }); the Rust compiler doesn't shut up and let us do it, in fact it complains even more, in addition to saying we can't do an out-of-bounds access it also warns that this unsafe block is futile, unsafe doesn't make bounds misses magically OK. † We can tell the Rust compiler we insist on seeing this through to the bitter end, it will emit the program, and then when this code executes there's a bounds miss and it panics. The default is to reject programs which always just panic when executed. |