4 ms·
The original claim was: > The borrow checker doesn't stop most memory errors, just the easy ones at the cost of making it painful to write basic data structure
by dundarious 4y ago
The original claim was:
> The borrow checker doesn't stop most memory errors, just the easy ones at the cost of making it painful to write basic data structures
I'm not the OP but I think the point here is that the borrow checker is only applicable for the "easy" code (which does make up an awful lot of code), but even "basic data structures" very often require abandoning the borrow checker. In such a case, it's perfectly accurate to say "the borrow checker doesn't stop most memory errors" since you must turn it off when you write the code responsible for "most memory errors" -- at least that is the case in my experience.
So in this type of discussion, consider arguments about the capabilities of "the borrow checker" as analogous to arguments about "the memory safety of Rust in general", rather than taking it so literally.
If you want to make a sensible argument on this front, it should be about unsafe belonging mostly in crates that have been thoroughly looked over and battle-tested by the community. That is after all, a major reason why the number of such errors is still impressively small. But unsafe errors are still Rust errors, and while the borrow checker is wonderful, it and Rust should still be held accountable for problems in necessary code that requires disabling the borrow checker.
I think Zig does pretty well on this front, with there being pros and cons to not having a clearly demarcated "unsafe" boundary built into the language. Lacking an unsafe keyword does make it more unsafe, but in my experience, not very much.
- Ar-Curunir 4y agoI maintain Rust cryptography libraries with over 30-40k LoC, and I have never resorted to unsafe to bypass borrowck. Our code is as performant as any C impl, without the memory safety bugs. There are many such libraries in Rust.
- dundarious 4y agoI wouldn't expect cryptography to need much unsafe. I've never worked in the area, but I expect code mostly falls into 3 domains: parsing, "business" logic (negotiating algorithms, checking certificates/signatures the right way, etc.), and actual crypto algorithms. I see great benefit for Rust in the first two domains. In the algo domain, I don't see how memory safety adds anything as memory issues are an insignificant problem. And there are big challenges like sometimes needing constant-time impls, etc., and how to do that without always having to dip down to hand-written assembly for each target platform. No language I know of provides help in getting bitslicing right, for example. Again, Rust is great for an awful lot of code, but we should still assess Rust's memory safety claims against the data structures code where you often need to disable the borrow checker. An awful lot of people only use safe wrappers around well-tested unsafe code, which is great, but the unsafe code is still being executed and may still have memory "unsafe"ty.
- davidatbu 4y ago> I don't see how memory safety adds anything [to algos in cryptography] as memory issues are an insignificant problem. I'm not terribly experienced in cryptography either, but I'm pretty sure that memory safety is a HUGE deal in cryptography as a whole. Heartbleed[0] was a memory safety issue. Python's cryptography package switched to Rust specifically because of memory safety [1]. [0] https://cve.mitre.org/cgi-bin/cvename.cgi?name=cve-2014-0160 https://cve.mitre.org/cgi-bin/cvename.cgi?name=cve-2014-0160 [1] https://github.com/pyca/cryptography/issues/5771 https://github.com/pyca/cryptography/issues/5771
- dundarious 4y agoHeartbleed was in the parsing/business logic areas -- the areas where I said Rust's memory safety provides great benefits. When I say crypto algos, I mean implementing S-boxes in 3DES, etc.
- davidatbu 4y agoIf you agree that Rust's memory safety is hugely beneficial in cryptography, then I'd love to hear other (sub)domains (e.g., kernel code, networking code, blockchain, ...etc) that necessitate tricky data structures, making Zig a better fit than Rust (which, IIUC, is your main point here).
- dundarious 4y agoI don’t have a “zig/rust is better than rust/zig” point here. The point was to say you have to judge Rust’s success against the unsafe code it occasionally forces you to write (you don’t get to hand wave it away), especially since a great example of such unsafe code is data structures code, and that is where a lot of my memory errors occur. Then we got diverted into some minor points about how much benefit does memory safety at compile time give you in different domains. I wouldn’t build a company or long-term project around Zig right now, since it’s quite young, so if the choice was just those two, I’d probably always pick Rust. But ignoring that, since Zig will probably “graduate” in a year or two: both are good for all those domains, and I’d be hard-pressed to say one is better or worse than the other without further constraints. Zig certainly seems less indirect and more lightweight, and has less of an immediate cognitive burden, but Rust’s additional burden there is providing some additional value. I really don’t like Rust’s allocation story though — AFAIK there are plenty of allocations in std that can only be controlled by swapping out the global allocator, possibly even at link time. C++ is clunky on this front too, just in a different way. C is “better” simply because the standard library is so meager, but that has never been a problem for me in practice.
- pcwalton 4y ago> Lacking an unsafe keyword does make it more unsafe, but in my experience, not very much. The problem is not "lacking an unsafe keyword", it's that Zig is not memory safe. Not being memory safe, in my experience, makes a massive difference.