to all of the statistical nerds out there counting memory errors in to justify the existence of : a logic error in a system that uses explicit memory management often culminates in a memory error. That doesn't make it a memory management error, it's still a logic error, and patching it up with more memory management is over-complicated at best and silently incorrect at worst.

@namark I don't think "patching with more memory management" is accurate. Rust focuses on *correctness* of ownership and mutability, especially at compile time.

By analogy to types: a logic error in a dynamically typed language often culminates in a type confusion ("undefined is not a function"). Does it mean that statically typed languages solving it with "more types" are over-complicated and silently incorrect at worst?

@namark In a statically typed language you annotate functions with types, so that when you make a logic error that causes passing nonsense data, it will be caught at compile time.

Rust is just a logical extension of that idea. You annotate functions also with memory management rules, so that when you make a logic error that causes incorrect sharing or freeing of data, it will be caught at compile time.

@kornel yes I would not count type errors such as "undefined is not a function" in dynamically typed language to statistically evaluate the usefulness of static typing, because I know there would be a lot of false positive that are caused by logic errors and not typing errors. Type conversion is a fix for a type error but it would not fix the underlying logic error. You have to fully understand the code, follow some guidelines or get lucky to identify the logic error from the type error, even if it is reported to you at compile time.

Correctness of memory management is not correctness of program.

@namark I'm surprised you're not seeing the analogy. Do you really not think that statically typed languages reduce defects in programs?

If you had traced 2/3rds of your bugs to type confusion (two + two == "22"), wouldn't you like static typing that makes these problems literally impossible to happen?
Note that rewrite from dynamic types to static types is not merely a hack that casts values, it's a logic-bug-discovering exercise, e.g. urllib3 found *logic* bugs sethmlarson.dev/blog/2021-10-1

@namark but besides, your reduction of Rust to just memory management is still inaccurate.

Rust also has sum types. Option replaces null, and makes it a compile-time error to not check for absence of a value. Result won't let you use values without checking for error condition.

Automatic destruction means there are no risky "goto cleanup" with confused state.

Mutex wrapping its content ensures you literally can't make a mistake of accessing the data without locking the mutex first.

@namark I also disagree with the generalization that all memory errors are symptoms of logic errors. They sometimes are, but there's also a fair share of just stupid direct mistakes, like not handling integer overflow in buffer sizes (e.g. stagerfright exploit) or using different buffer length when allocating vs copying. These can be eliminated by construction (you can't have a logic bug in code that doesn't need to be written).

@kornel you are either completely missing the point, or intentionally derailing now, go read the OP, I'm talking about statistic of memory errors in c++, and it's use as an indication of how important/common memory errors that rust eliminates are. It's useless because most logic errors result in memory errors in c++. You are counting these logic errors towards your total of memory management errors. And once again logic errors are not memory errors, that's what I'm trying to explain to you, while you keep imagining that I said that all memory errors are logic errors.

@namark I understand, and I think the statistic is still valid.

1. There are memory errors that are directly related to "logic" of memory management, not a symptom of a deeper error, and fixing just memory management would fix 100% of the problem, with absolutely no hidden more problems.

2. Rust does not just focus on the case 1 as you imply. It does prevent deeper logic errors too, so it can help with ultimate root causes of logic errors that manifest as memory errors.

@namark

3. in secure contexts merely stopping exploits matters, even if it doesn't fix things properly (that's why we have sandboxes etc.). A logically buggy program that misbehaves, mangles data, and crashes is still better than a program that misbehaves and allows RCE instead of crashing.

So even if your presumption that Rust fixes merey memory errors, and lets other bugs fester behind a coat of paint, that is still a valuable improvement for safety.

@kornel now you are literally arguing that most logic errors are memory errors, that's how religious you are about your beloved language.

Here is a pseudocode example to demonstrate to you a logic error, that results in a memory error, that is not itself a memory error, or has nothing to do with memory management. This is apparently utterly incomprehensible to you:

got some resource x
if(condition)
some operation that invalidates x
use x

memory error on last line... how do you solve this problem? You could replace the first operation with equivalent that does not invalidate. You could replace x with an equivalent shared resource that does not invalidate on that operation. You may take a copy of x, and keep the original for use after invalidation. You may rearrange the code so that the second use comes before the condition. All of these options will solve the memory error, but none of them would be correct. The correct solution in this contrived example is to return early in the condition body(or add an else after the if, or whatever other branching technique you use), and never use x in that case, because it was an error condition for that particular subroutine. You will never know this from the memory error alone, you need to understand the business logic of the piece of code, to figure that out. The memory error was not the cause, or even a hint of what the problem is. In fact it was a distraction.

And fixing memory errors without fixing the logic is not better than nothing, it's worse, because it complicates the code and lets the underlying logic error "fester behind a coat of paint". Otherwise it's a segfault. Both are equally bad for security but that is beside the point. Any discussion of silent bugs vs a loud bugs is about development and maintenance, not security. For security any kind of bug in a critical part of the program is a disaster.

@namark As for your example, it is interesting, and it is what Rust addresses.

You would get an error such as "x used after a move".

Rust functions define ownership, so "some operation" could invalidate x only if took ownership. Therefore, returning in that conditional would be the only way to make it compile. Unless you decide to refactor "some operation" to borrow temporarily instead, and then the caller would have a choice.

@namark You're claiming that this complicates and distracts, but I disagree.

Functions clearly declaring if they invalidate or only view their inputs clarify their intent. They require programmers to think which is the right solution (with guidance from the compiler).

In Rust you would not get a segfault either way. Not because it'd hide the memory error, but because it'd force logically correct sharing or moving of data, according to how function interfaces are explicitly designed for.

@kornel are you even reading what I'm writing or are you just a rust commercial? I don't think I can chew it up any further for you, just try again if you will, and present a better argument, I can't engage any further with you bringing up points unrelated to what I'm saying, I'll have to just repeat myself.

@namark We're clearly talking past each other.

I think I understand your argument, but we have different perspective and assumptions, so when presented with the same information, we draw different conclusions. That's why I'm trying to add context/background to the discussion which affects my judgement, but you may find it unrelated or irrelevant, because that's not what you have based your judgement on.

@kornel you are assuming I don't know the very basics of the languages I'm talking about and spewing out unrelated marketing slogans. But alright I'll try one more time and hope you'll put a bit more effort into it. I assure you, I'm not trying to destroy you favorite language, or definitively prove that it is entirely useless (I'll do that later maybe). I'm making a very specific point. So here we go again:

Memory errors are not impossible in rust, they are possible they just happen at compile time. My example was in pseudo code and conceptual, so whether the error happens at compile time or runtime doesn't matter. My point is that the error in question has nothing to do with memory management, and cannot be solved with memory management techniques, it's a completely unrelated logic error. If you solve the memory error in the most obvious way you will not solve the logic error. You can satisfy the rust compiler, but the problem will still remain. Therefore rust by the virtue of being rust does not eliminate this class of errors that statistically you would count as memory errors in C++, because that's how they are more often than not manifested technically. If you find yourself inclined to pursue the route of "it's better than nothing" again, I addressed that when I presented the example and in the OP, so please take that into consideration and continue with arguments from that point. If you think that regardless of all of that rust is still useful, that's fine, but irrelevant.

Follow

@kornel *but irrelevant in this particular context

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.