GC-proof resource classes
Timon Gehr via Digitalmars-d
digitalmars-d at puremagic.com
Sat Aug 29 15:50:42 PDT 2015
On 08/29/2015 05:20 PM, cym13 wrote:
> On Saturday, 29 August 2015 at 14:32:27 UTC, Timon Gehr wrote:
>> But then classes with destructors shouldn't be allowed to be allocated
>> on the GC heap in the first place, which is a PITA as well. (Note that
>> classes/arrays can have destructors because some component structs
>> have them; structs generally assume that their destructors will be
>> called.)
>
> I don't quite follow the reasonning here. If GC doesn't call the
> destructor then this same destructor is no more than a normal method
If it is no more than a normal method:
- Why have special syntax for it?
- Why should Object have it?
> (with restrictions... would those still stand?) that is the default
> destruction method to be called by things like scoped!T or destroy if
> explicit destruction is needed.
> ...
If there is a destructor, this (usually) means that explicit destruction
is needed.
Again, note that if I have
import std.collection: Array;
class C{ Array arr; ... }
then now C implicitly has a destructor (that does nothing but call arr's
destructor which may in turn free memory on the C heap).
Constructor and destructor are supposed to frame the lifetime of an
instance. Destructors are in the language so that the language can help
with enforcing this. If there's a built-in and expected way to violate
this property, the syntactic similarity of constructors and destructors
is misleading, and the features are less useful.
> I think there should be a separation of concerns that isn't possible
> right now. Freeing ressources and freeing memory isn't the same thing
> and they should be decoupled.
Memory is a resource, and not all memory is allocated by the GC. (c.f.
http://erdani.com/d/phobos-prerelease/std_experimental_allocator.html)
> I think a destructor is there to free
> ressources, and the GC is there to free memory. If the GC doesn't call
> the destructor then why should having a destructor have anything to do
> with the GC?
>
> Or do you fear for classes whose memory would be freed before freeing
> its ressources?
For example. The general idea is that there is no point in having
language features to deal with complex issues if they actually don't.
> That could be a problem... In that case I think the best
> option would be to allow them to be allocated by the GC
I assume this means allow 'new Class()' even if Class has a destructor.
> but GC-ing it if
> the destructor hasn't been called should spawn an error (or something
> like that, haven't taken the time to think through it).
Why is it sensible to have the same syntax for allocation if
deallocation/destruction needs to be handled differently?
> Or maybe it shouldn't be marked as garbage if the destructor hasn't been called.
> ...
I.e. leak memory.
> I think of it as a simple switch hasDestructorBeenCalled that would be
> set to true if no destructor exists or if it has been called, and false
> otherwise, and would prevent GC-ing (or crash... I don't know what's
> best) of the object if false.
>
> That way simple classes stay simple,
Simple classes get an additional hidden field. Even the monitor field is
too much.
> complex classes can live on the
> heap happily without fearing collection while being able to reliably
> free ressources.
This does not make a lot of sense. If there is no live reference to a
class managing a resource and it would then need to "fear" collection,
this means that the resource has been leaked.
More information about the Digitalmars-d
mailing list