Mixing safe and unsafe
Mixing safe and unsafe
Posted Oct 29, 2025 21:07 UTC (Wed) by tialaramex (subscriber, #21167)In reply to: Mixing safe and unsafe by matthias
Parent article: Fil-C: A memory-safe C implementation
That's why I was so concrete about things. In Rust they are now nailed down. The compilers are still crap, so if you bang on this hard it'll miscompile, but that's true in C and C++ anyway, it's just harder to prove you were miscompiled because often you'll write UB in those languages and the compiler people will use that as an excuse. But that's not a language issue, that's a compiler QOI issue and I expect over the next 3-5 years it'll improve, the way the LLVM's handling of aliasing improved when Rust began banging on it and filing bugs.
You're wrong about the special-ness of one-past-the-end in Rust. It's not special in Rust, it's just one past the end. Sixteen past the end, or eight before the start, or any other value is fine too. Like I said, in Rust pointers actually are the imaginary tuple (addr, addr_space, provenance) and we're always allowed to get addr out by definition. In C and C++ whether that can work is hotly contested, see the recent "Pointer zap" LWN article for a taste of how insane C might be here and what its committee members want to do about that.
Rust distinguishes validity for read versus write, and provides explicit methods on pointer types, so the correct way to initialize that uninitialized memory pointed to by ptr that's the right shape for a Goose, is the (unsafe obviously) ptr.write(some_goose); and yes, that pointer was valid for writing only up until that moment, though having performed a write it's now valid for reads too.
If you're thinking "I would use a dereference" Bzzt, that's going to be a problem. unsafely *ptr = some_goose; will try to destroy the previous goose, but there is no goose, just uninitialized memory so that's UB.
