1. Early detection. You can't fix a bug that you don't know about.

In C/C++ bugs can easily stay latent, because they may depend on conditions that rarely happen or just be lucky and "asymptomatic" thanks to freed or uninitialized data happening to have acceptable values.

In Rust, when it points out "x used after invalidated", you at least know there's something wrong, so you have a chance to fix it (correctly or not). If you didn't know about the problem, it'd definitely remain incorrect.

2. Ownership, sum types, borrow checking, send/sync thread-safety are not purely memory management features.

So to your argument that memory errors are merely symptoms of other errors, I say that Rust expands features that you classify as mere memory management fixes into broader tools that encompass some types of logic errors too.

Show thread

For example, if you have a logic bug in code like "do B then A", but logically it should have been "do A, then B", it can have a use-after-free symptom in C/C++ indeed.

In Rust this will have a symptom of use after move compile-time error, where the fix from memory management perspective will have overlap with the fix from logical perspective.

e.g. file.close() can take exclusive ownership. It not only prevents UAF, but also catches logic bugs that manifest in reading file after closing it.

Show thread

In case it's not clear what I mean, in other words:

closing the same fd twice is not a memory error, and it's harmless from security perspective, but it is a logic error. Idiomatic Rust style "abuses" ownership machinery for enforcing "can't read after close" logical requirement even beyond places that manage memory. So things that have memory-management-like symptoms in Rust can be more directly related to logic constraints expressed using types.

Show thread

@kornel I had this in mind when writing everything I wrote but I do not conciser closing an fd twice a logic error, it's a resource management error, which for the purposes of this discussion is same as memory error, equivalent to double free. I wrote "resource" in my example intentionally to somehow hint at that. It could be a heap allocated object, an fd, or a container-iterator pair, with the iterator being the part that gets invalidated, or whatever else that fits the pattern. It should really be called resource safety in general, but I was following the convention here.

Btw, in case you didn't know, this resource management generalization comes directly from C++, and has been a thing there since forever.

@namark Preventing these "resource" errors is what Rust does well, IMHO.

But let's say Rust only solves the resource errors, and doesn't address the logic errors that may be their root cause.

Would you say that C++ solves or prevents these root-case logic errors?

Follow

@kornel no c++ does not automatically prevent such logic errors, my point wasn't that it does, my point was that this class of errors skew the statistic of memory errors that rust can help fix reliably. Exactly how much can only be shown empirically, but I haven't seen anything like that mentioned or addressed anywhere. Most statistics seems to be based on technicalities and not root causes.

Sign in to participate in the conversation
Qoto Mastodon

QOTO: Question Others to Teach Ourselves
An inclusive, Academic Freedom, instance
All cultures welcome.
Hate speech and harassment strictly forbidden.