4 ms·
Who would write two separate but equivalent codebases, one which manages memory with RAII and another that assumes a GC, just to use that value for something? I
by fluoridation 3y ago
Who would write two separate but equivalent codebases, one which manages memory with RAII and another that assumes a GC, just to use that value for something? If you're already not assuming a GC is present then why rewrite every a second time assuming it's not?
- layer8 3y agoThis is probably aimed at libraries designed to be compatible with both kinds of environments. A library might implement some localized alternative logic to maximize efficiency in both cases. C++ is all about maximum runtime efficiency while allowing libraries to provide comprehensive compile-time abstractions.
- fluoridation 3y agoA library that uses RAII instead of relying on a GC should work with or without a GC.
- layer8 3y agoRAII requires allocation patterns to coincide with lexical scopes, or to use reference counting, which is usually more expensive than GC. If RAII were all you need, no one would be using GC in the first place.
- deeviant 3y agoRAII ties resource management to lexical scope but doesn't strictly "require" it. Reference counting vs. GC cost varies by context—neither is universally "more expensive." Both RAII and GC have their merits; their use depends on the language and application needs, not on one being strictly superior.
- layer8 3y agoRight. I could also have said “If GC were all you need, no one would be using RAII in the first place”. No contradiction here. So it can make sense for a library to support both, to accommodate different application needs.
- ori_b 3y agoHow would you write a library to support both without being fully RAII correct? And if it's fully RAII correct, isn't the GC is a no-op?
- layer8 3y agoThere are several ways I can think of. For example, a library that stores application-provided elements (e.g. a graph library where nodes/edges can carry application-specific data) can support by-value RAII elements as well as by-reference GC’d elements and by-reference library-memory-managed elements (using new/delete). As another example, the destructor of a library-provided class might have to free a complex internal heap-based substructure, a potentially expensive operation (having to iterate over the substructure) that it can skip (only) when running under a GC.
- ori_b 3y agoThat's kinda the point: you can't skip it with RAII, unless you avoid exiting a scope (longjmp?). I suppose you can have two versions of the class, and instantiate the leaky one only if you have GC, but that seems like work that the GC should free you from. It seems better to optimize the memory allocations, perhaps with an arena.
- layer8 3y agoNot sure what you mean. My point is, for the case of no GC, you have to provide a destructor, even if the work done by the destructor only consists of freeing memory. With GC, calling the destructor could be omitted if it only frees memory. Client code however doesn’t know what a destructor does internally, so always has to call it even under a GC. The implementation of the destructor, however, can check whether it is running under a GC, and can then skip the freeing. Edit due to your edit: An arena allocator isn’t always convenient, for example when you have multiple objects with different lifetimes that move and/or partially share internal elements between them, so the element lifetimes are largely orthogonal to the containing object’s lifetimes.
- rightbyte 3y agoYou can RAII into global scope too though. Unless you count that one as lexical. RAII into a stack and you got dynamic scope.