August 02, 2005
>> 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
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
>> 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
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
> 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
"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
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


1 2 3
Next ›   Last »