Hacker News new | ask | show | jobs
by SkyMarshal 3344 days ago
Think of Rust as a better C - when you need low-level hardware control like C enables, Rust gives you that + guarantees about never having memory segfaults or concurrency errors that C can't. If your Rust program compiles, it won't break for those reasons (unless you intentionally enable and use unsafe code, but not by default).

Think of Go as a better Python (scripting) or Java (application) language - simpler than Java, faster and with better concurrency than Python. Like Python and Java it's garbage-collected, like Java it's statically weakly typed so can't offer the level of guarantees that Rust can, but possibly faster to develop in as a result. Still too new and thus lacks the extensive libraries of either Java or Python, but growing fast.

1 comments

I managed to crash compiled Rust programs in my brief experience with it.
What kind of crash? Rust's memory model guarantees memory safety, meaning you can not have: use after free; double free; buffer overflows; index out-of-bound issues; etc.

What it doesn't prevent is crashes. Rust programs will crash if your program tries to do any of the above, and-or blindly unwrap() Result or Option types.

Now Rust can segfault, etc., just like Java, Node, Go, Ruby, Python, PHP and every other "memory-safe" language when using unsafe or native extensions.

I think it was an index out of bounds type error. Can't quite remember.

To be clear, it was my inexperience with Rust, rather than a the language that was the problem. I found it amusing when I had read a few comments saying that "if it compiles it will run".

The person you were replying to said it will run without certain types of errors, not "it will run".
Yes, that would be a panic.
> index out-of-bound issues

You sure about that? You can still get Rust to panic if you try to index a vec past the end...

A panic is significantly different than an actual out of bound access; the latter is the cause of a lot of issues, but a panic is preventing those issues.
Ah I get you! You can't read past the end of an array, but you can get an error.
Exactly!
So isn't the memory model more to do with the compiler or operating system rather than the programming language? Do think it's possible to write a C compiler that checks for use after free, double free, buffer overflows, index out-of-bound issues, etc.?

Surely if one programming language can do it, another can?

A C compiler that checks for all of these things at runtime is Valgrind. It's used when testing.

A C compiler that checks all of these things at compile time would no longer be a C compiler.

Compile time guarantees require you to change the language and restrict what is allowed to compile. Rust does just that, it's a different language. You could write an extension to C like Cyclone (or the ISOCPPCore guidelines for C++) that make it safer via compile time checks. You would likely need more annotations and most existing C programs would no longer compile.

(There is the ergonomic benefit of being able to transition from a C codebase to a, say, Cyclone one, though)

It's not possible to write a C compiler that guarantees what Rust guarantees. There are just too many implicit assumptions about pointers. Even if you check most cases, weird stuff like XOR linked lists will trip you up. (And sure, if you changed the language you could make it safe -- but then it wouldn't be C anymore.)
> Do think it's possible to write a C compiler that checks for use after free, double free, buffer overflows, index out-of-bound issues, etc.?

No, due to the way the language semantics works.

There are static analyzers that do something like that, MISRA-C, High Integrity C, Frama-C, but you are literally using C with Ada semantics at that point, thus it is almost like another language.

Of course, and many programming languages offer similar features as Rust. I've not used Ada myself, but people claim it offers similar safety features.

From my experience though, Rust is the first language that I've had the pleasure to use which offers both the safety guarantees of Java (and more, no data races!) and the low level features of C.

It still leaves me in awe what has been accomplished with Rust, and I've been using it for more than two years now.

For arbitrary C code, I believe checking for those issues is equivalent to the halting problem. Or at least uncomputable.
Rust doesn't guarantee no crashes. It guarantees protection against certain errors e.g. use-after-free and out-of-bounds indexing, some of which can't be done statically at compile time, so if Rust didn't crash e.g. when you index an array out-of-bounds, it wouldn't be doing its job.

It'll also let you do whatever you like if you write `unsafe` code.

It's not actually "whatever" you want. It drops a number of restrictions, but still guarantees some others that C doesn't for instance.

https://doc.rust-lang.org/book/unsafe.html

And unsafe is tagged. You don't have to look at the entire codebase, just the few unsafe blocks. Those bugs are often subtle. Any way to restrict where to look is super helpful.
Sure - I bet you've seen a panic - but I'm relatively sure you've not seen a segfault, buffer overflow, or corrupted memory issue. A panic tells you where the issue is (or close to it) - the other issues could only show signs that they exist far away from where they were caused.
You are not alone. Being memory safe doesn't mean bug free or panic free. This does not invalidate any of the comments, it is a fairly good low level language with a compiler that helps you to catch nasty issues at compile time.

The main complaint imho is that despite the many speed improvements, it's still not the fastest of the compilers. But it's getting there!

One of the big gains they still have to make IIRC is providing partial compilation. That will be significant with the good developer practice of breaking source code into multiple files.
I personally don't think that compilation units should be driven by files. Too often have I been forced to keep something in the "wrong" place in C++ because of the compilation model. (This happens in rust too, due to other reasons)

Instead, the compiler should figure out what needs to be recompiled and do just that. This can mean benefits like not needing to recompile everything because you added a comment to a header file.

Unfortunately, doing that at a particularly interesting scale - so I could have, for example, automatic compilation as I type into my editor, meaning hitting "run" would be near-instant - means rearchitecting the compiler to behave closer to Roslyn, which is a huge task.
Oh, sure, it's kinda a pipe dream to get something like this for C++ (use ccache instead). But Rust is still forming its story here (we have experimental incremental compilation which does this!) and I see no reason to constrain it by tying it to files :)
Rust cannot protect you from all forms of crashes, even work only safe code. OOMs, and stack overflows, for example, are easy to create deliberately, and possible to create accidentally. Rust focuses more on safety, in terms of correctness, not crash proof.