
Emil Dotchevski wrote:
On Sat, Apr 25, 2009 at 10:47 AM, Edward Diener <eldiener@tropicsoft.com> wrote:
Raindog wrote: That is why I think that a real solution to using RAII and GC in C++ must come from the ability to tag objects at the class level, and only occasionally at the object level
I agree with most of what you're saying, I myself am not a fan of GC however I do appreciate its benefits in some cases, when all of the resources being managed allow non-deterministic termination (memory being the most important such resource.) Yet, occasionally even memory needs to be managed deterministically.
I agree with your last statement. See the end of my last paragraph below.
So I disagree with your assertion that classes should be tagged for GC, and not individual object instances.
In the ideal scheme classes which encompass non-memory resources should actually be tagged as non-GC, so RAII would automatically kick in for dynamically allocated objects of those classes; otherwise dynamic allocation uses GC. I also said that there are cases where individual object instances can be "tagged" and of course this must be allowed for any object. I just think that ideally tagging classes as RAII would cover the majority of the situations. Individual object instances, as an example, could occur when a container of RAII dynamically allocated objects is created and it is then important to "tag" the container itself as RAII, where otherwise it would be considered GC by default.
One of the best features of shared_ptr is the fact that it abstracts resource management at object instance level. I know this is wishful thinking, but the ideal solution as far as I'm concerned would be to implement GC as a custom (non-deterministic) allocation strategy, per-instance, as a custom shared_ptr allocator.
I don't think that it is easy to have user of an object decide for every object whether it is RAII or GC, which one would have to do with your ideally proposed shared_ptr<> custom allocator scheme, unless of course shared_ptr were made smart enough to understand the "tag" of the type of object it is encompassing and use its custom allocator accordingly in a default situation. It is normally much easier for the class designer to know whether the class is RAII or not, and much easier for the user of an instantiated object of that class just to instantiate the object and then not worry whether its destruction is deterministic or not. The whole point of a system of dynamically allocated memory being a smart combination of deterministic RAII and non-deterministic GC is that as much of the burden as possible, in determining RAII or GC, should be taken off the user of objects as possible so the code is not littered with endless manual decisions. Certainly the designer of a class knows with 99% certitude whether an object of his class needs RAII or not. In the very few run-time cases where a class could encompass either RAII or GC objects, or both, ( STL containers are the proverbial example ) then the user of that class has to have his say. Similarly if I am allocating one million, let's say, instances of GC object in a container, I should certainly have the ability of making that container RAII so I can release all that memory as soon as possible.