Destructor semantics

foobar foo at bar.com
Tue Aug 10 15:09:53 PDT 2010


Steven Schveighoffer Wrote:

> On Tue, 10 Aug 2010 17:23:39 -0400, foobar <foo at bar.com> wrote:
> 
> > Steven Schveighoffer Wrote:
> >
> >> On Tue, 10 Aug 2010 16:33:08 -0400, foo <foo at bar.com> wrote:
> >>
> >> > In light on recent discussions of clear() and the distructor it seems  
> >> to
> >> > me that we are going backwards from one of D's great improvements over
> >> > C++ - the difference in semantics between structs and classes.
> >> >
> >> > IMO, instead of enhancing class desteructors they should be completely
> >> > removed and only allowed on structs with deterministic semantics and  
> >> all
> >> > uses cases of class desteructors should be replaced with structs.
> >> > Examples:
> >> > class SocketConnection : Connection {
> >> > // struct instance allocated inline
> >> > SocketHandle handle;
> >> > ...
> >> > }
> >> >
> >> > OR:
> >> >
> >> > class SocketConnection : Connection {
> >> > struct {
> >> >    this()  { acquireHandle(); }
> >> >   ~this() { releaseHandle(); }
> >> > } handle;
> >> > ...
> >> > }
> >> >
> >> > The suggested semantics of the above code would be that creating a
> >> > SocketConnection object would also construct a SocketHandle as part of
> >> > the object's memory and in turn that would call the struct's ctor.
> >> > On destruction of the object, the struct member would be also  
> >> destructed
> >> > and it's d-tor is called. This is safe since the struct is part of the
> >> > same memory as the object.
> >> >
> >> > in short, struct instances should be treated just like built-in types.
> >> >
> >>
> >> That doesn't help.  deterministic destruction is not a struct-vs-class
> >> problem, its a GC-vs-manual-memory problem.  A struct on the heap that  
> >> is
> >> finalized by the GC has the same issues as a class destructor.  In fact,
> >> struct destructors are not currently called when they are heap-allocated
> >> because the GC has no idea what is stored in those memory locations.
> >>
> >> -Steve
> >
> > Let me add to the above, that the GC should NOT manage structs allocated  
> > on the heap. structs should only provide deterministic semantics.
> 
> So either you are saying that structs that are in classes are never  
> destroyed, and you have a resource leak, or every class has an  
> auto-generated destructor that calls the struct destructors, and we have  
> the same determinism problem you purport to solve.  If a struct is in a  
> class, it's on the heap.  You have not solved the problem.
> 
> -Steve

Sorry for the confusion, my explanation wasn't good enough. Let me try again:

We have 4 different cases:

case 1,  class contains a struct:
a.  the sturct is not an independent block of memory. Instead, it is part of the same memory block of the class instance's memory. 
b. every class has an auto-generated destructor that calls the struct destructors. This is safe because of the point a. 

case 2, class contains a class:
this has same non-deterministic semantics as today. The containing class cannot call the dtor for the contained class.

case 3, struct contains a class:
struct dtor calls deterministically the auto generated dtor for the class (clean any member structs of the class)

case 4, struct contains a struct
c++ deterministic dtor sementics. 

if you allocate a struct instance on the heap you have to deallocate it (NOT GCed) and the explicit delete would trigger the deterministic dtor behavior.

example:

struct A { ~this(); }
class B { A a; }
struct C {B b; ~this(); };
auto foo = new C();
...
delete foo; // [*]

when we reach [*], this is what will happen:
C::~this() is called
  B::~this{} is called // this is ALWAYS auto generated
    A::~this() is called

in memory we have two separate memory blocks; 
the first contains an instance of C (this includes a ref to a B)
and the second contains an instance of B which also contains _inline_ an instance of A. 


More information about the Digitalmars-d mailing list