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 Sure, Rust copied RAII and moves from C++, but made moves the default, and removed possibility of accessing an empty state left after a moved value.

Rust needs to compare itself to C and C++, because it targets specifically the market cornered by these languages. And yes of course, people who propose Rust as a solution to issues in C/C++ programs do think Rust works better, and the improvement is worth the switch.

@kornel I didn't mention c++ here to claim it is better in this particular regard, I mention it to call you out on writing paragraph that reads like an ad for resource management generalization in rust, in a thread about comparing rust to c++, which supported that since forever. I didn't mean specifically that rust copied RAII and moves, I mean it copied "whatever you can do with memory you can do to any other resource" generalization.

@namark Thanks. So I see how I could misinterpret your original toot.

My understanding now is:

1. "memory error" category of bugs is not the whole picture => misleading.

2. Rust "patching up with memory management" addresses wrong things.

With 1, I see your point. I would quibble about how often it is the case, but ok.

With 2, I don't agree. It's not "patching up". Rust's features are broader and improve correctness beyond mem management.

@kornel for 2 my point isn't that rust is always wrong, or that all things considered it does a worse job here than c++, my point is that the memory safety alone can't provide a strong guarantee that these errors will be fixes once diagnosed. The error might be fixed, or might be obfuscated, dependent on other factors, such as overall expressiveness of the language or the discipline of the programmer. You can argue that rust is more expressive or coherent, but that would be a completely different, much more subjective and complicated discussion, compared to the basic sales pitch of "all bajillion of these memory* errors I counted will 100% entirely go away".

@namark Rust doesn't promise 100% fix of course, but it does promise (and IMHO deliver) a substantial reduction that is worth talking about.

Predicting whether a bug detected through safety features will be truly properly diagnosed and fixed entirely, is too speculative to argue with. You're pessimistic. I'm optimistic. I don't think I can convince you here, because it's about predicting future behavior of hypothetical people fixing hypothetical issues. My imaginary rustaceans do it well 😀

@namark I can tell you that I did feel change in types of bugs I wrote when I switched from C to Rust. In my experience these features do help clarify thinking about data flow in the program, its architecture, and provide good blocks and vocabulary for using threads reliably. I used to debug runtime bugs & fudge things until they stopped crashing. I now I think in terms of data flow instead. I haven't gotten smarter, but my bugs changed from memory sprays to missing features and asserts firing.

Follow

@kornel it's not that hard for a language to be more expressive than C. I'm glad you upgraded.

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.