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.

Reply via email to