|
|
|
|
|
by vvanders
1424 days ago
|
|
Yep, my favorite part of heap/stack corruption is not when it crashes immediately but rather when it rears its head 2-3 weeks/months later when some upstream call pattern or timing has changed. I've spend weeks chasing down single instances of this on multiple projects. The nasty part is you have no predictability in if it's going to be one that crashes immediately, silently writes garbage(hopefully not to disk!), is a latent lurking crash or security vuln. If you trash the stack then there's a good chance you lose the backtrace as well which can make a hard to debug issue become "find the needle in the haystack". I hope it's something that reproduces quickly and consistently because otherwise you're in for a ride. |
|
These days you use `std::unique_ptr`, build with clang-tidy, CI under ASAN, and it's never an issue in practice. Once in a blue moon the CI chirps an ASAN failure that gives you the entire history of the memory address with line numbers and you fix the typo.
The safety that Rust gives me is that it's more expressive type system and modern affordances for things like exhaustive pattern matching lets me avoid logic errors, which are every bit as deadly as buffer overruns and much harder to mechanically identify.
It is usually easier to write correct code in Rust than in C++ because it's much more modern and frankly kind of an everyman's Haskell (which I mean as a compliment). But it's intellectually dishonest to say that this doesn't come at a cost: when you wander out of the borrow checker's sweet spot it can become kind of a Tetris puzzle even when you know all the rules on paper.
The same pattern matching that lets people see a borrow checker puzzle and immediately say "right, we need to do X" is the pattern matching that let's a C++ hacker see a failed template instantiation and immediately know what got misspelled.