What's the use case of clear?

Lutger lutger.blijdestijn at gmail.com
Tue Aug 10 11:22:23 PDT 2010


Steven Schveighoffer wrote:

> On Tue, 10 Aug 2010 13:01:37 -0400, Lutger <lutger.blijdestijn at gmail.com>
> wrote:
> 
>> Honestly I think that clear() as it does too much, but this is what I
>> think was
>> intended:
>>
>> Class Connection {
>>    invariant() { assert( pool !is null); }
>>
>>    ConnectionPool pool = null;
>>    bool isOpen = false;
>>
>>    this() {
>>       pool = ConnectionPool.get();
>>       enforce(pool !is null);
>>    }
>>   this(string connectionString) {
>>       this();
>>       connect(pool, connectionString);
>>       isOpen = true;
>>    }
>>
>>    ~this() {
>>       disconnect(pool, connectionString);
>>    }
>> }
> 
> No, this is bad.  ~this cannot access any GC resources.  Although you
> forgot to store it, connectionString may be a GC-allocated resource, so it
> may be invalid by the time the destructor is called.  The only way to fix
> this is to malloc the string:

You are right, I ignored that issue. This example is broken.

> Class Connection {
>     private string connectionString;
> 
>     ...
> 
>     this(string connectionString) {
>         this();
>         connect(pool, connectionString); // note, we use the GC'd version
> in case connect stores it.
>         this.connectionString =
> (cast(immutable(char)*)malloc(connectionString.length))
[0..connectionString.length];
>     }
> 
>     ...
> 
>     ~this() {
>        // since I malloc'd connectionString, I know the GC didn't collect
> it.
>        disconnect(pool, connectionString);
>        free(connectionString.ptr); // clean up my non-GC resources
>     }
> }
> 
> In fact, it might even be illegal to use pool.  If at the end of the
> program, the pool is destroyed, and then your object gets destroyed, you
> are screwed.
> 
> It is one of the severe limitations of the GC.  I wish there was a way to
> mark a piece of memory as "owned", that would be nice to have.  But even
> then, you need to own all the data you deal with in the destructor.  You
> can't rely on simple pointers to objects you don't own, they may be
> invalid.
> 
> -Steve

Again you are right, this only works for non-gc owned resources. Frankly at this 
point I wonder how to even begin use class destructors for anything interesting, 
especially in the wake of clear(). Did you ever write one? 

The spec says that this restriction does not apply when the users calls delete 
since it isn't collecting then (also applies to clear), but I don't think there 
is any way to detect that.


More information about the Digitalmars-d mailing list