4 ms·
Rust Memory Management Explained
- sesm 2y agoRust is a subset of C++ with extra static checks. All the core decisions are the same as in C++: - RAII - Lock-based concurrency - In-place mutation People get confused when they hear that Rust is 'related to ML' and has Refs, but Rust Refs have nothing to do with ML Refs: ML Refs are mutable pointers to immutable data, Rust Refs are pointers to data mutated in-place. Reference counting is not 'Rust memory management' it's a well-known technique with well-known problems, and Rust doesn't bring anything new to the table here. Edit: RIAA -> RAII
- sapiogram 2y ago> Rust is a subset of C++ with extra static checks. While this may work as a rough heuristic, it's not true in theory nor in practice. First example that comes to mind: Rust has proper sum types (Called enums), which are used everywhere, and C++ doesn't have anything like it.
- vaylian 2y agohttps://en.cppreference.com/w/cpp/utility/variant https://en.cppreference.com/w/cpp/utility/variant
- jstimpfle 2y agoAs far as I've seen, std::variant's ergonomics isn't remotely competitive with rust sum types. C++ lacks the syntax.
- flohofwoe 2y agoYet they're both conceptually the same old thing: tagged unions. In C++ everything is just more awkward since everything is bolted on as an afterthought in the stdlib but then lacking language syntax sugar to make its usage convenient. E.g. the (somewhat weird looking) equivalent to Rust's match is called 'visit' in C++: https://en.cppreference.com/w/cpp/utility/variant/visit2 https://en.cppreference.com/w/cpp/utility/variant/visit2
- zaphar 2y agoI can create tagged unions in literally any language not just C++ including Assembly. Rust having syntactic and compiler checked support for them as a foundational part of the language is a material difference in the design that differs fundamentally from C++. So the the point still stands.
- pjmlp 2y agoSyntax is on its way...
- lvass 2y agoSource?
- pjmlp 2y agoThere are at least three proposals in flight for C++26, if they reach an common agreement on time, or it has to be done by C++29, remains to be seen. Just search for the various revisions, https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/ https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/
- jstimpfle 2y agoI'm not even using Rust but I think you should stop hyping things that won't exist for years as if they were real and proven, like you've been doing a lot. I've had a quick look at one of the proposals behind the link and it's no comparison with the existing Rust way. Even std::variant itself is a crutch (being templatized by a list of types), not comparible with true algebraic datatypes.
- sapiogram 2y ago`std::variant` is a clever piece of template hackery, but it doesn't come close to Rust enums. `std::variant` has no named variants, no pattern matching, no exhaustiveness checking. In Rust, it's not unusual to have an enum with dozens of variants, good luck doing that with std::variant. I'm sure you could technically emulate all this in C++ is you keep throwing template metaprogramming at it, but at that point anything is a C++ subset and the statement loses all pratical meaning.
- pjmlp 2y agoPattern matching is on its way, one of the possible approaches being discussed, https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2688r1.pdf https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p26...
- leftyspook 2y agoComing right after profiles are done, probably?
- pjmlp 2y agoOne has nothing to with the other. That is the thing with committee driven languages, with multiple vendor implementations. Not everyone is on the same room voting for the same features, and not everyone is implementing the features in any specific order. By the way, I would rather have Safe C++ than profiles, but do not vote, so whatever.
- leftyspook 2y agoI'm not saying they are related, just saying that the committee committeing is going to take half a decade at least for both.
- pjmlp 2y agoWell, it is still going to be faster than WG14 ever doing anything useful improve the C's security model regarding arrays and strings. It has hardly moved since 1989, and annex K doesn't count, given its broken design. Anyway I am still mostly stuck with .NET Framework, Java 17, node 20 in many commercial deployments, so it isn't like everyone cares that much to update to latest, given existing business decisions. Those kind of industries don't care about programming language featurities anyway.
- codr7 2y agoI don't even think Bjarne could claim with a straight face that hacking variants into the standard library was a good idea :)
- pjmlp 2y agoHe only gets one vote among 300 something committee members, so his opinion while important, is largely irrelevant. By the way, ever noticed that after C89, neither Ritchie nor Dennis ever had anything else to do with how WG14, or the compiler industry vendors, decided to take C onwards? The original Plan 9 C compiler isn't even standards compliant.
- hgomersall 2y agoAlso the move semantics of rust completely change how you reason about variables.
- malkia 2y agorecently learned that move semantics in C++ leave the moved-out object in this weird state... and this after almost 25+ years of using C/C++ - lol....
- ryukoposting 2y agoI believe you mean RAII. Though I suppose I've seen no evidence against the notion that Rust likes the Recording Industry Association of America. Jokes aside, I think the biggest difference between Rust and C++ lies in metaprogramming and generics. Rust macros are a trip. Rust's sum types and traits are also much more deeply integrated into the syntax of the language than std::variant or concepts.
- sesm 2y agoThanks for spotting the typo :)
- ubj 2y ago> Rust is a subset of C++ with extra static checks This is like saying that Julia is a subset of Python with JIT compilation. Rust and C++ have some conceptual similarities, but they are entirely different languages.
- zozbot234 2y ago> All the core decisions are the same as in C++ Not at all. In a Rust program, all objects are supposed to be movable via a memcpy (i.e. a bitwise copy) by default. Immovable objects are only supported as an afterthought, via the Pin<> featureset (which is widely regarded as unintuitive, clunky and in need of revision). C++ objects are immovable by default; alternately, they may support custom "move" operators that are closer to the way .take() is used in Rust, i.e. they leave behind the original object in some sort of undetermined state. These are quite significant differences that make it hard to have consistent interop across both languages.
- sesm 2y agoThis is interesting. If I want my object to be movable without the need for acquiring the locks for all outbound references, I need my references to be of type 'reference to mutable data'. So that could be one of the reasons why Rust reference types are like this. But what happens to inbound references when I'm moving my object? Who is in charge of updating them?
- steveklabnik 2y agoYou get a compile time failure. There is no mechanism to automatically update them.
- sesm 2y agoOk, I see now. This is limited to cases when compiler can prove that the reference is not shared, but still can be useful when adding elements to collections.
- steveklabnik 2y agoYeah, among other things. It can be used to implement “session types” which basically means encoding a state machine in the type system. So for example, I’m building a web application at work, and users have permissions to access resources. The “please grab a foo from the database” function takes an Authorization as a parameter by move, so in order to call it I have to get one. The only way to get one is to ask the auth subsystem, which checks if a User has the proper permissions. And the only way to get a User is to ask the auth system to authenticate that they have a valid session. So as long as I make my “fetch resources” code require an Authorization as a parameter in the future, I’ll also guarantee that all of the rest of that stuff happens. It’s a little verbose but pretty cool.
- deleted 2y ago[deleted]
- sylware 2y agoI want to have fine-grained and full control over memory management. Can rust generate usefull machine code without a runtime and having to break one leg like C?
- MaulingMonkey 2y ago> I want to have fine-grained and full control over memory management. Rust's global allocator is easy enough to replace on stable: https://doc.rust-lang.org/std/alloc/trait.GlobalAlloc.html https://doc.rust-lang.org/std/alloc/trait.GlobalAlloc.html Per standard container allocators ala C++'s std::allocator haven't been stabilized, but are available on nightly: https://doc.rust-lang.org/std/alloc/trait.Allocator.html https://doc.rust-lang.org/std/alloc/trait.Allocator.html Alternatively, you can roll your own allocator ecosystem easily enough - my limited foray into this is mostly focused on interop with specific 3rd party allocator APIs from C, C++, Win32, etc.: https://docs.rs/ialloc/ https://docs.rs/ialloc/ , there are plenty of crates focusing on arena allocation etc. instead. > Can rust generate usefull machine code without a runtime and having to break one leg like C? Yes. At one extreme, you can create #![no_std] crates ( https://docs.rust-embedded.org/book/intro/no-std.html https://docs.rust-embedded.org/book/intro/no-std.html ) which don't assume you can create threads, write to stdio, or even allocate heap memory. I've gotten Rust static libraries linking into "unsupported" platforms in minutes (when it had an LLVM-compatible linker available.) At the other extreme, I've previously ported Rust's standard library to an unsupported NDAed platform. It's easy to stub out unsupported bits - the code for such stubs already exists to support wasm32-unknown-unknown (arguably a mistake, but it's a useful one!) - and replacing those stubs with real code isn't too onerous in my experience either. Middle grounds of `extern crate alloc;` let you support subsets of "the standard library" as well. Yanking all "runtime" support out of existing platforms might be a bit trickier (e.g. there's a little code to support populating std::env on *nix, a little mucking with default signal handling, and e.g. windows builds will use Win32 APIs for backtracing and unwinding for panics - ripping that all out is more obnoxious, but also pointless IMO.) Some non-NDAed examples of targeting funky stuff: • https://github.com/MaulingMonkey/uefi-hello-world https://github.com/MaulingMonkey/uefi-hello-world (why write hello world for windows when you can directly boot hello world?) • https://github.com/MaulingMonkey/rust-opendingux-test https://github.com/MaulingMonkey/rust-opendingux-test (old, linuxy - see Notes.md, consider using -Zbuild-std instead of Xargo these days?)
- hotjump 2y ago"Rust memory management explained" (excluding borrowing) is TBH wild. Without borrow checker Rust safety guarantee is nothing new
- eptcyka 2y agoThere are many other posts like this, I struggle to see what this one brings to the table. To understand how Rust manages memory, one should refer to the rust book instead - it will be a richer explanation originating closer to the source.
- pjmlp 2y agoIt is the Rust's version of the Haskell's burritos blog posts of 15 years ago, every time someone finally understood the M word.
- deleted 2y ago[deleted]