|
This article has a core point which is good: “in Rust the default is safe, and you have to opt-in to unsafety, but in C++ the default is unsafe, and you have to opt-in to safety”. I think it’s easy to argue for Rust using this construction, because, well, that’s the entire point why Rust was created. But, it really doesn’t take a very long post to talk about this. The remainder goes off the rails, talking about “C++ apologists” (hint: if you’re being “fair”, pick words that are unlikely to cause people to be preemptively upset. This is not one of those words) and their stupid opinions. And the author just trashes them as being complete idiots, but it’s obvious that the arguments come from inexperience or strawmen, which just makes the overall thing not particularly convincing. Saying that the various UB finding tools were useless because you tried using them and didn’t get good results is stupid. Being smug about “people who use modern C++ clearly can’t do HFT, which is the thing that you said you were using C++ to do” is also insipid, just because you spotted the use of a shared_ptr somewhere and read how it’s not zero-cost. Modern C++ has other things in it, you know, many of which are zero-cost and significantly (but not entirely) safer; picking one thing and misrepresenting it does not make for a good refutation. Anyways, coming from someone who writes a lot of C++ and would also like a lot of code to be migrated to Rust for good reasons, it’s a good idea to approach the tradeoffs honestly and without disdain for those who aren’t convinced yet. The core argument I mentioned above and the closing part of the article does do this…but there’s a lot in the middle that doesn’t, and it drags down the usefulness of the post. |
On the subject of safe defaults, just to correct that Rust does not in fact have as much default memory safety with regards to buffer bleeds (e.g. variants of OpenSSL's Heartbleed) as it could [1], because it has unchecked arithmetic (integer wraparound) as the default for performance, with checked arithmetic only as an opt-in for safety.
In other words, if an attacker can get some bounds merely to underflow (as opposed to overflow) then they can still read the sensitive memory of a Rust program, even without a UAF or buffer overflow.
Bleed vulnerabilities like these are also low-hanging fruit and significantly easier to exploit.
In other words, bounds checking only ensures you are within the buffer, but checked arithmetic is still needed to ensure that your index was correctly calculated in the first place.
I believe that Rust would be much safer against memory bleeds, if it had checked arithmetic enabled by default for safety, with an opt-out at the block scope level for performance, like Zig has.
[1] https://news.ycombinator.com/item?id=29991439