5 ms·
What is really good about Rust that you cannot get in C?
by skor 5y ago
What is really good about Rust that you cannot get in C?
- mvolfik 5y agoI'd guess guaranteed memory safety (unless you use `unsafe` blocks) without compromising for some garbage collector or ref. counting is a big thing
- whb07 5y agoCompile time guarantees that you didn’t access memory you didn’t really “own”. Dangling pointers are not a thing. No double free. Forces you to think up front about what are the possible state something could be in, and so you won’t get runtime or weird UB. lastly, to be more pedantic for everyone who is at Linus-levels, it’s like all the best static analysis and warnings/errors all rolled up natively into the language. Please don’t bombard me with “but I can just run clang’s X and get the same thing”. No you can’t, and if you did this forces you to run it regardless.
- The_rationalist 5y agoIt's quite trivial to enforce the use and absence of X warnings/error from a static analysis tool Y during merge review and CI. C++ with ASAN enforced is quite close, not compile time granted but much more familiar. Btw there are lifetime checker for c++ in development.
- emilfihlman 5y agoAll easily achievable with gcc. Yes, we can.
- bicolao 5y agoPlease show us how. I don't think these can be achieved within current C semantics.
- masklinn 5y agoIn full anyway. Limited subsets? Sure, if you assign a null and immediately try to deref' it Clang and GCC will probably notice and yell at you.
- whb07 5y agoWell, no. You’re talking about using all the flags and tooling like i just mentioned, which 99.99% of people don’t use every time they run a build. Even then the best and strictest of flags + Werror still falls short. Then you still have to run extensive fuzzing and testing to trigger different paths and whatnot. Or you could just use Rust.
- wffurr 5y agoThe main benefit is that in Rust, use-after-free, data races, and bounds overflows are statically checked with zero runtime cost. It eliminates entire classes of common severe memory safety bugs at compile time.
- 0x008 5y agoIt's not about if you can get there but how fast and at what cost.
- volta83 5y agoThe ability to refactor large code bases quickly without introducing segmentation faults, memory bugs, UB, etc.
- lemmox 5y agoI came for the memory footprint but I stayed with Rust for this. Rust became my daily-driver for hobby projects because refactoring and tinkering with old projects is a breeze. For me, Rust projects don't seem to require much cognitive burden to load into my human memory. I do not claim that this quality is unique to Rust however it is very much present in Rust.
- goodpoint 5y agoWhat is really good about Rust that you cannot get in Nim?
- geofft 5y agoSafe, GC-less memory allocation. Nim requires a GC, at least runtime refcounting, in order to not leak memory: https://nim-lang.org/docs/gc.html https://nim-lang.org/docs/gc.html The ownership/lifetime system is basically novel to Rust (well, it's based on Cyclone, which would probably have been an interesting choice for the kernel too because it's based on C, but Cyclone is no longer actively developed), and it allows you to get the performance of manual memory management (no refcounting required) without either leaking memory or hitting use-after-free bugs. Rust's ownership system also tracks shared/immutable references and unique/mutable references at compile time, avoiding a whole bunch of setups for creating race conditions or otherwise corrupting data.
- goodpoint 5y agoNim is memory-safe and compiles to C, which is a big plus for integrating an existing C codebase. > Rust's ownership system also tracks shared/immutable references See https://nim-lang.org/araq/ownedrefs.html https://nim-lang.org/araq/ownedrefs.html
- geofft 5y agoIf I understand correctly, that post describes a proposal to add "owned refs" to Nim, not an actual language feature, and that proposal was abandoned / postponed in favor of the refcounting approach I linked to: see https://github.com/nim-lang/RFCs/issues/144 https://github.com/nim-lang/RFCs/issues/144 and https://github.com/nim-lang/RFCs/issues/177 https://github.com/nim-lang/RFCs/issues/177 . But shared/immutable vs. unique/mutable references aren't the same thing, they're something more interesting. Rust has three types of ways you might be able to get at a variable: you could own the variable, you could have a shared/immutable reference to it, or you could have a unique/mutable reference to it. The Nim proposal only distinguishes the ownership case (responsible from freeing the data when it's done - basically RAII or __attribute__((cleanup)) or autorelease) from the unowned case. Having shared/immutable references gives you a neat feature for achieving correctness, not just memory safety (and I strongly disagree that the idea of "memory safety" in that post really counts, incidentally, because by that definition Heartbleed wasn't a memory-safety bug, but for the sake of argument let's say it does). The compiler prevents you from having more than one mutable reference at a time. It also prevents you from writing data you own while someone holds a reference to it, or even reading data while someone holds a mutable reference. So if you're writing code where you pass a reference to some other routine, and that function ends up holding onto it for future use, you won't be able to modify it. That prevents logical bugs where code doesn't realize that data has changed or conversely doesn't realize that a change hasn't taken effect. Again, this is not solely about memory safety. This is about easily writing correct code, of which memory safety is one aspect. You can think of this as basically type-level reader/writer locks. At any given time you can have multiple readers and no writer, or exactly one writer. While runtime memory safety is one thing that reader/writer locks can do (e.g., preventing you from calling realloc() while other people still have a pointer that they intend to read), they're used for a lot more than that. Furthermore, Rust's approach requires no runtime overhead and preserves correct behavior. Nim's approach requires refcounting, and the post argues that refcounting could be disabled in a release build if you're confident your code is correct.
- garrinm 5y agoIt'd be very hard to make a statement like "Rust can do X that C can't" without there being a statement "You can do Y, then Z in C and that is like X" because clearly they are both Turing complete languages at the end of the day. So I'll instead just give reasons why people might prefer to program in Rust: - Memory management / safety (no GC, variable lifetimes are tracked by the compiler, no dangling, no null pointer ...) - Ergonomics (built-in unit tests, feature-full std lib, unicode strings, modern dependency manager, more formalized macros ...) - Functional-lite (you must explicitly discard unused enum variants, the "null" value is an enum variant ...) Long story short: Rust makes it really easy to write sound software. I think you see that on crates.io where Rust packages are hosted. Lots of packages quickly reach maintenance mode and receive very few updates, but remain extremely useful. Once you've written (compiled) something in Rust, you feel much more confident that is is free of latent runtime bugs. Without commenting on whether or not this is necessary or good for the Linux kernel, I'll say that there are probably many devs out there that feel like working other non GC languages feels like pulling teeth after having worked with Rust. And that might be part of the pressure.
- ozarkerD 5y agoI love cargo. That alone almost makes it worth it to me after years of wrestling cmake and dependency compilation.
- gpm 5y agoNote that the kernel won't use cargo to build most (or all) of the rust code. Though dealing with rust dependencies by hand is usually nicer than dealing with C dependencies by hand because the build process is more standardized.
- swiley 5y agoNPM style package management :p But there are some significant improvements WRT memory management/indirection.
- gpm 5y agoApart from all the safety benefits mentioned, a modern language with modern conveniences. Type inference Language support for tagged unions (which they call enums for some reason), which among other things results in error handling which is "out of channel" instead of magic return values. Speaking out error handling - syntax for easily forwarding errors to the calling function. Generics, and therefore - Libraries of collections with a rich collection of methods implemented for you. - Library support for lazy iteration - ... Method (postfix call) syntax allowing for readable chaining Hygenic macros Compiler supported test harnesses Compiler supported linting (that is really good) Compiler supported automatic formatting (that is really good) Compiler supported vtables (pointer, length) strings Proper namespaces And so on and so forth
- cesarb 5y ago> Language support for tagged unions (which they call enums for some reason) Probably because the simplest case of Rust enums (without any data other than the tag itself) can act similar to a C enum, to the point that you can "#[repr(C)]" it and use as FFI for the equivalent C enum. One understated advantage of Rust for C programmers (which is on topic given that the Linux kernel is written mostly in C) is that its syntax and keywords have many similarities with C, starting with the use of braces for blocks and semicolons to end statements.
- gpm 5y agoYa, that was a throwaway comment that I probably should have left out. > and use as FFI for the equivalent C enum. Only if you're willing to accept undefined behavior if the foreign code passes you an unknown variant. For actual ffi work I've ended up using a macro that makes a "#[repr(C)] struct EnumName(u32)" with a bunch of constants for the values.
- kzrdude 5y agoThat wouldn't be ABI-correct for ffi function parameters by value, right? (Since it's a struct, not an enum).
- Macha 5y ago1. Modern standard toolchain 2. Ergonomic use of functional idioms like sum types (Rust's enums) 3. Memory safety without GC overhead - Windows, Linux, curl, over and over again 40% of vulnerabilities in larger C projects are found to be preventable if there was a memory safe language