3 ms·
Even of the error originates in unsafe code, the UB can manifest elsewhere. The optimizer makes assumptions that you can easily invalidate in an unsafe block le
by galangalalgol 3y ago
Even of the error originates in unsafe code, the UB can manifest elsewhere. The optimizer makes assumptions that you can easily invalidate in an unsafe block leading to UB. In many ways it is mich easier to introduce UB in an umsafe block than it is in C++. But at the very least you know the UB originated in one of your unsafe blocks. Its just figuring out which one. I very rarely use unsafe outside bindings though, so that helps too.
- GolDDranks 3y agoThe nice thing is that you can check the invariants at some reasonable module boundaries. The bugs in unsafe code can manifest elsewhere, but at least, when wrapped properly, someone _else's_ bugs won't cause your unsafe code to have UB.
- DSMan195276 3y agoThe problem I personally have is the "when wrapped properly". Functionally it's the same issue as "just write correct C code", but the invariants that have to hold in Rust aren't as well defined (because there's more of them). Writing "correct" `unsafe` code is a lot harder than it seems on the surface. There's also the issue that I've seen it commonly advocated to keep `unsafe` blocks small - which makes intuitive sense, but brings into question whether `unsafe` is supposed to _just_ mark the unsafe operations being done, or mark all the code under which certain assumptions have to hold for UB to be avoided and it be 'safe'. It's been a little while since I looked into it, but there wasn't much agreement on this the last time I looked and I've seen people do it both ways.
- Veliladon 3y ago"When wrapped properly" is a lot more likely to happen in Rust because idiomatic Rust involves things like proper error handling and returning Result for fallible operations. I use libraries that have gobs of unsafe all the time. Wgpu is basically an unsafe code factory because it glues Rust to C and C++ but all of its unsafe code returns Options and Results because Rust programmers get them all drilled into them by the community and all the learning resources said community provides.
- GolDDranks 3y agoHave you written unsafe code in Rust? I have some experience writing unsafe code, and most of the time you can do it without problems, wrapped in sensible safe APIs that don't allow unsafety to leak. Of course, this needs experience and knowledge about API design and the invariants that must be followed... and preferably another set of eyes. The thing is that once you've managed to do that, the _consumers_ of your API are free from worries. The situation becomes a whole lot better than the equivalent C situation, where both sides of the API need to be careful about what funny abominations the another side might devise.
- DSMan195276 3y ago> Have you written unsafe code in Rust? I have some experience writing unsafe code, and most of the time you can do it without problems Yes, I've written a decent amount of `unsafe` code. And I would also point out, C programmers say the same thing about their code :P The problem comes when an assumption you thought was ok turns out to be something the compiler writers thought you shouldn't do, and then your code is broken. Rust doesn't have a defined list of invariants you can't break in `unsafe`, which makes it pretty hard to be confident you didn't break one of them. I've loosely followed the work to pin down some of these things[0], but I don't personally feel like tons of progress has happened and they've been working on it for years. That said don't get me wrong, I like Rust, I just wish the `unsafe` situation was improved. I also agree that creating safe APIs around `unsafe` code is the way to go, but I've seen a whole bunch of people get it wrong due to bad advice given around `unsafe` or lack of clarity around what `unsafe` is actually supposed to mean. `unsafe` has also IMO been overloaded to mean both "this code does one of the unsafe operations" or "this code has some invariant you must keep". The latter tends to be the better way to go for creating APIs, but is also harder to do and ends up causing you to mark completely safe code with an `unsafe`. [0]: https://github.com/rust-lang/unsafe-code-guidelines https://github.com/rust-lang/unsafe-code-guidelines
- stouset 3y agoThe general rule of thumb is to ensure you've returned to safety guarantees before exiting an unsafe block. Obviously it's too much to expect humans to be perfect at this, but having that mentality makes it orders of magnitude harder to leak UB into safe code. The overwhelming majority of violations I've seen are where engineers dip in and out of unsafe code without upholding safety guarantees inbetween.
- galangalalgol 3y agoThe one I usually see is an unsafe method leaving memory aliased.
- WirelessGigabit 3y agoCan you share an example so I know what to look for?
- galangalalgol 3y agoIf an unsafe function borrows an input make sure it doesn't return an aliased reference to the same data.