View mode: basic / threaded / horizontal-split · Log in · Help
August 02, 2005
Re: Ordered Destruction was: Re: Destructor Bug?
>> Generally speaking, destructors called by the garbage collector are not
>> terribly useful, for the reasons you mentioned. Destructors called when  
>> they
>> go out of scope (i.e. auto objects) are very useful.
>
> What about getting the compiler to complain if there are sub-object  
> member
> references in the destructor of a non-auto object, since they are not  
> allowed?
> Would that be possible? It'd be an improvement.

Hmm, but sub-object references are allowed for auto objects and objects  
that are explicitly deleted... This somehow seems like a design weakness  
to me. :(

Ciao
uwe
August 02, 2005
Re: Ordered Destruction was: Re: Destructor Bug?
Hi,

>>> Generally speaking, destructors called by the garbage collector are not
>>> terribly useful, for the reasons you mentioned. Destructors called when  
>>> they
>>> go out of scope (i.e. auto objects) are very useful.
>>
>> What about getting the compiler to complain if there are sub-object  
>> member
>> references in the destructor of a non-auto object, since they are not  
>> allowed?
>> Would that be possible? It'd be an improvement.
>
>Hmm, but sub-object references are allowed for auto objects and objects  
>that are explicitly deleted... This somehow seems like a design weakness  
>to me. :(

Yeah, but those would be fine. Auto-objects would be allowed. Delete Object
would be allowed. Everything else (which is illegal, if I'm not mistaken), is
disallowed. Right?

Cheers,
--AJG.
August 02, 2005
Re: Ordered Destruction was: Re: Destructor Bug?
>> Hmm, but sub-object references are allowed for auto objects and objects
>> that are explicitly deleted... This somehow seems like a design weakness
>> to me. :(
>
> Yeah, but those would be fine. Auto-objects would be allowed. Delete  
> Object
> would be allowed. Everything else (which is illegal, if I'm not  
> mistaken), is disallowed. Right?

Yep. But how should the compiler know that?

####
class SomeClass
{
  SomeOtherClass m_cl;
  // ...

  ~this()
  {
    m_cl.doSomething();
  }
}

SomeClass[] array;
int main()
{
  array ~= new SomeClass;
  array ~= new SomeClass;
  delete array[0];
}
####

In this case the compiler would have to conclude that the second object in  
the array will be found by the GC. How to do that during compilation time?

Ciao
uwe
August 02, 2005
Re: Ordered Destruction was: Re: Destructor Bug?
Hi,

>>> Hmm, but sub-object references are allowed for auto objects and objects
>>> that are explicitly deleted... This somehow seems like a design weakness
>>> to me. :(
>>
>> Yeah, but those would be fine. Auto-objects would be allowed. Delete  
>> Object
>> would be allowed. Everything else (which is illegal, if I'm not  
>> mistaken), is disallowed. Right?
>
>Yep. But how should the compiler know that?
>
>####
>class SomeClass
>{
>   SomeOtherClass m_cl;
>   // ...
>
>   ~this()
>   {
>     m_cl.doSomething();
>   }
>}
>
>SomeClass[] array;
>int main()
>{
>   array ~= new SomeClass;
>   array ~= new SomeClass;
>   delete array[0];
>}
>####

>In this case the compiler would have to conclude that the second object in  
>the array will be found by the GC. How to do that during compilation time?

Ohhhhh... I see what you mean now. So if you call explicit delete on the _super_
object, then its destructor can safely access sub-object references, is that
correct?

That's just confusing and error-prone in my opinion. So depending on how it's
deleted (GC vs. explicit) an object might (a) work perfectly, or (b) crash hard
with a segmentation fault.

I don't think that kind of design (and the behaviour that it causes) should be
encouraged. I'm not sure what the compiler can do but I think it's a problem
that should be thought about.

I think (for now) maybe the compiler should emit at least a warning when
referencing sub-objects in the destructor, given the hidden danger of doing so.
Although fundamentally, the real solution would be to fix the GC so that it can
deal with full-featured destructors.

Cheers,
--AJG.
August 02, 2005
Re: Ordered Destruction was: Re: Destructor Bug?
> Ohhhhh... I see what you mean now. So if you call explicit delete on the  
> _super_
> object, then its destructor can safely access sub-object references, is  
> that correct?

Exactly. Perhaps this would be a solution to your problem?
August 02, 2005
Re: Ordered Destruction was: Re: Destructor Bug?
"Walter" <newshound@digitalmars.com> wrote in message 
news:dcn7ss$1drb$1@digitaldaemon.com...
> Generally speaking, destructors called by the garbage collector are not
> terribly useful, for the reasons you mentioned. Destructors called when 
> they
> go out of scope (i.e. auto objects) are very useful.

This got me thinking about the uses of auto classes I've seen in D so far 
(note by auto objects I assume you mean an instance of an auto class). I've 
run into 4 auto classes: MmFile, ExeModule, PerformanceCounterScope (in 
phobos) and ScopedLock (in the locks library). The first two shouldn't be 
auto IMHO and MmFile is no longer auto. The last two are auto in order to 
ensure an action is performed at scope exit - either stop a performance 
counter or release a lock. Both of these auto classes can be replaced with 
the following auto class. By using this ScopeExit one can separate the 
concept of dtor called by the GC from the dtor called by exiting a scope. 
Also by reusing ScopeExit one can avoid ever having to define an auto class 
by hand.

// the only auto class you'll ever need
auto class ScopeExit {
   void delegate() dg;
   this(void delegate() dg) {
       this.dg = dg;
   }
   ~this(){ dg(); }
}

// example
class Foo {
   void close() {
       printf("closing a Foo\n");
   }
}
int main() {
   Foo f = new Foo;
   {
       auto ScopeExit exit = new ScopeExit(&f.close);
       printf("before exiting scope\n");
   }
   printf("after exiting scope\n");
   return 0;
}

Replacement code for the two auto classes PerformanceCounterScope and 
ScopedLock the code would look something like

 PerformanceCounterScope scope = new PerformanceCounterScope(counter); // 
original
 ScopeExit exit = new ScopeExit(&counter.stop); counter.start(); // new 
code

 ScopedLock scope = new ScopedLock(lock); // original code
 ScopeExit exit = new ScopeExit(&lock.unlock); lock.lock(); // new code
August 02, 2005
Re: Ordered Destruction was: Re: Destructor Bug?
In article <dcojar$2ggu$1@digitaldaemon.com>, Ben Hinkle says...
>
>
>"Walter" <newshound@digitalmars.com> wrote in message 
>news:dcn7ss$1drb$1@digitaldaemon.com...
>> Generally speaking, destructors called by the garbage collector are not
>> terribly useful, for the reasons you mentioned. Destructors called when 
>> they
>> go out of scope (i.e. auto objects) are very useful.
>
>This got me thinking about the uses of auto classes I've seen in D so far 
>(note by auto objects I assume you mean an instance of an auto class). I've 
>run into 4 auto classes: MmFile, ExeModule, PerformanceCounterScope (in 
>phobos) and ScopedLock (in the locks library). The first two shouldn't be 
>auto IMHO and MmFile is no longer auto. The last two are auto in order to 
>ensure an action is performed at scope exit - either stop a performance 
>counter or release a lock. Both of these auto classes can be replaced with 
>the following auto class. By using this ScopeExit one can separate the 
>concept of dtor called by the GC from the dtor called by exiting a scope. 
>Also by reusing ScopeExit one can avoid ever having to define an auto class 
>by hand.
>
>// the only auto class you'll ever need
>auto class ScopeExit {
>    void delegate() dg;
>    this(void delegate() dg) {
>        this.dg = dg;
>    }
>    ~this(){ dg(); }
>}
>
>// example
>class Foo {
>    void close() {
>        printf("closing a Foo\n");
>    }
>}
>int main() {
>    Foo f = new Foo;
>    {
>        auto ScopeExit exit = new ScopeExit(&f.close);
>        printf("before exiting scope\n");
>    }
>    printf("after exiting scope\n");
>    return 0;
>}
>
>Replacement code for the two auto classes PerformanceCounterScope and 
>ScopedLock the code would look something like
>
>  PerformanceCounterScope scope = new PerformanceCounterScope(counter); // 
>original
>  ScopeExit exit = new ScopeExit(&counter.stop); counter.start(); // new 
>code
>
>  ScopedLock scope = new ScopedLock(lock); // original code
>  ScopeExit exit = new ScopeExit(&lock.unlock); lock.lock(); // new code

Neat! I like the idea.

Cheers,
Holger
Next ›   Last »
1 2 3
Top | Discussion index | About this forum | D home