4 ms·
> because automatic deallocations lead to hard-to-predict lifetimes (excess memory usage, and bugs for resource handles that are destructed at hard to predict m
by coder543 4y ago
> because automatic deallocations lead to hard-to-predict lifetimes (excess memory usage, and bugs for resource handles that are destructed at hard to predict moments).
I don't really feel this is the case in Rust.
- throwawayzr 4y ago
- varajelle 4y agoBut it is. If you have a String on the stack, it's memory is only reclaimed at the end of the scope, while it often could be free'd before. This is especially bad in async code around await point since it means the memory need to be kept alive more than needed.
- coder543 4y agoI disagree. It is substantially and unequivocally better to hold onto memory until the end of scope than to leak memory by default. How can anyone argue that leaking memory is a better default? That’s a ticking time bomb. Maybe someone is so optimistic as to believe they’ll catch every leak before shipping new code? You can easily add a manual “drop” call in Rust at any point if you want to force an allocation to be freed sooner, but I speak from years of experience using Rust for work when I say that Rust’s RAII model is not problematic in practice. I’m not simply speculating or theorizing, and I have professional experience with a variety of languages at all levels of the stack. I personally don’t mind garbage collectors most of the time, but Rust is great when you need more control. In C++, RAII can absolutely be problematic because you are able to easily do things that cause undefined behavior by accident, which is arguably worse than either leaking by default or the mere act of holding onto memory for the duration of a scope. If you can propose a system which cannot be contrived to have any downside, that would be fantastic! In the real world, Rust’s approach to memory management is extremely pragmatic and beneficial. I’m sure someone will eventually improve on Rust’s approach, but “leak by default” isn’t it. I honestly do enjoy following Zig… it is a fascinating language taking a really interesting approach to solving many problems, but its memory safety story is not where I want it to be yet. Leaking memory by default is technically safe, but it's not exactly endearing.
- varajelle 4y agoOf course you can call drop() manually, but almost nobody does or even think about it because that's not the way you program in a language with RAII. Don't get me wrong. I do think that rust and c++ RAII is much more convenient and safe than the C or Zig way. (I'd even prefer if you could annotate given struct in rust so the compiler could drop them as soon as it's no longer used, but that s not that simple)
- coder543 4y agoI definitely wish that Non-Lexical Lifetimes would eagerly drop anything that doesn't implement Drop. It would probably be a breaking change to automatically call an explicit Drop implementation anywhere other than the end of the current scope, so I think that would have to be left as-is. String doesn't implement Drop, so it could easily be dropped eagerly within the scope as soon as it won't be referenced again. Such a change would be roughly equivalent to any of the compiler optimizations that reorder statements in ways that should be unobservable.
- ______-_-______ 4y ago100%. I would actually go further and say every value should be dropped immediately after its last use, including temporaries in the middle of statements, whether or not it implements Drop. Reuse the same rules that NLL uses. Breaking change yes, so do it next edition. It would lower memory usage in general and solve so many little pain points, not least of which is holding strings across await points.
- varajelle 4y agofn foo(xx : &Mutex<String>) { let lock = xx.lock(); let ptr = &mut *lock as *mut String; unsafe { use_from_c(ptr) } } You get the idea: you don't want the lock or the string to be dropped before the unsafe code, even if the actual string is no longer used. That's the breaking change. It's hard to detect automatically, so hard to justify even in an edition.
- _3u10 4y agoStacks are a fixed size. Unless you are running out of stack space there is no point in “freeing” memory from the stack. Where in the stack the stack pointer points has no bearing on stack size for any OS I’m aware of. I’m assuming by string you mean a stack allocated array of char and not a std::string.
- varajelle 4y agoI meant a std::string on the stack, which is just a handle for more memory on the heap
- pcwalton 4y agoThis doesn't match the experience of GC'd languages. I've never heard of problems in practice that arose from treating all values present on the stack/registers as GC roots, even if those values are dead in the data flow sense.
- kaba0 4y agoYou can just put a single pair of bracket around it and that’s it. For locks it is seriously the best way to manage them.