5 ms·
By that measure C++ and Rust are a GCd languages because they have smart pointers.
by chobytes 7y ago
By that measure C++ and Rust are a GCd languages because they have smart pointers.
- otabdeveloper1 7y agoYes and no. "No GC" means "no mandatory GC when data isn't shared between threads".
- the_duke 7y agoNo because in Rust and C++ using smart pointers is an explicit choice that is applied manually when required and is present both in the type signature everywhere a reference counted type is used, and in the construction of values. In Swift the reference counting is a implementation detail of automatic and transparent memory management. (that you only really have to care about when you have cycles) That's why Swift definitely counts as a GC language for me. Sure, if you put things behind a Arc<T> or shared_ptr you use reference counting in C++ and Rust, but it is not an inherent feature of the language.
- chobytes 7y agoARC only applies to reference types. The programmer has acess to value types, and manual memory management if they want it.
- 0815test 7y agoIn Rust, using smart pointers is not much of an "explicit choice" - it's simply the idiomatic thing to do when something might be kept around by more than one parent object. Rc<T> basically means that there are multiple sources of control over T's lifetime, but these are all within a single thread; and Arc<T> signals that the control might extend to multiple threads. It's not "mere implementation" that we're dealing with here; it's the very semantics of the code as it relates to Rust's expanded take on the well-known RAII pattern. Swift simply lacks an equivalent to either the Rc<> specifier or e.g. Rust's Box<>, which expresses the semantics of an object which is heap-allocated and accessed via an indirection, and verifiably has at all times a unique "owner" controlling its lifetime (as per usual RAII).
- steveklabnik 7y agoYou can argue it’s an explicit choice because you can often choose to structure your code in a way that doesn’t require Rc. Of course, it exists because sometimes, you do have to or want to, but those cases are pretty rare in my experience.
- jerf 7y agoThis is why I say memory management isn't "either GC'ed or manual", because it's a continuum between "fully manual" (runtime hands you a slab of bytes, you do the rest) and "fully automatic" (you never worry about anything, not even cycles in the values, and it all "just works"). Between those two extremes there's a lot of gradation, not to mention the fact that all schemes can generally be mixed within a single program, language/runtime permitting. Thus, arguing whether some particular middle point is or isn't "garbage collection" isn't anywhere near as useful as people seem to suppose, especially if it's being argued in a context where "GC is morally bad in all forms" or something like that. It's all a bunch of tradeoffs and there is no single perfect answer to all problems. Note that even most "manually allocated" languages don't actually fall into my manual extreme; generally something more granular and automatic than that is offered. However, while nothing except arguably raw assembler defaults to that "fully manual" allocation, it's a useful last-ditch option in a lot of places, often wrapped up with just a touch more automation into something called "arena allocation", where you don't care about where the arena lives in RAM per se and it integrates with the rest of your allocator otherwise, but is just a big slab of bytes otherwise. Even in the GC'd languages I've seen "just give me a big slab of bytes and go away" used, even if it has no formal support. Personally, I'd consider "reference counting" as a "garbage collection" scheme if the references are counted automatically, and as manual memory management if you're in a context where you have to manage them manually, but YMMV. I break it down that way mostly because in the automatic case, you get the general advantages of automation, in that it's largely correct but often somewhat slower (because it can't elide anything), and managing them manually permits more sophisticated schemes but also is massively error prone (to the point I wouldn't use it for anything anymore; the benefits are available from other techniques and the costs are insanely high). So personally I'd go with smart pointers being an embedded method of garbage collection in a language/runtime that generally is written for manual memory management. It doesn't make the outer language a GC'ed language, nor is it some sort of betrayal of the manual memory management ethos or whatever. Real programs in C++/Rust at scale will tend to use lots of memory management techniques, many of them with high degrees of automation, but the language and runtime themselves are generally manually-managed. It doesn't matter how many smart pointers your program uses, arena allocation is always an option for your next bit of code.
- 7y ago