Destructor semantics

Steven Schveighoffer schveiguy at yahoo.com
Wed Aug 11 07:25:41 PDT 2010


On Wed, 11 Aug 2010 10:03:41 -0400, foobar <foo at bar.com> wrote:

> Steven Schveighoffer Wrote:
>
>> On Tue, 10 Aug 2010 20:28:32 -0400, bearophile  
>> <bearophileHUGS at lycos.com>
>> wrote:
>>
>> > Jonathan M Davis:
>> >> If attempts to use any reference types in destructors were a
>> >> compile-time error
>> >> with a clear error message, that could go a long way in stopping  
>> people
>> >> from
>> >> trying to misuse destructors.
>> >
>> > This sounds like a positive idea, maybe fit for an enhancement  
>> request.
>>
>> No, reference types are not necessarily heap allocated.  Guys, the
>> distinction is heap vs. manual, not reference vs. value.  Value types  
>> can
>> be on the heap, and references can refer to non-heap data.
>>
>> Adding artificial restrictions that force casting are not going to help  
>> at
>> all.
>>
>> -Steve
>
> I disagree. The distinction should be owned vs. not-owned and NOT heap  
> vs. manual. Hence values vs. references.
>
> Simply put:
> case 1)
>   struct S;
>   class C { S s;} // a C instance *owns* a S instance

Yes

>
> case 2)
>   class B;
>   class C { B b; } // a C instance does *not* own a B instance

No, the ownership of b is not clear because we don't know what b is for.   
A class is allowed to own referenced data, ownership is an abstract  
concept.  Whether C is responsible for cleaning up b depends on whether 1)  
it is GC allocated or not, and 2) whether the user specifically requested  
the destruction of C.

Here is a better example:

class C { private FILE *fp; }

C is responsible for cleaning up fp, because fp is a *NON-GC-ALLOCATED  
REFERENCE*.

I can also find ways to allocate a B so it is a non-gc-allocated  
reference.  If I have a restriction that I can't access B, then the  
compiler is disallowing valid code, and that is unacceptable.

But that is besides the point.  If C owns a B, and C is being destroyed  
with its b reference intact, it can clean up b immediately knowing that  
nobody is referencing its B.  Your solution doesn't allow that, all it  
allows is what we have now, but with worse requirements.

Again, restricting access to references both introduces artificial  
problems and does not solve the original problem.  It's a lose-lose.

> I believe that anything more complicated would require Bartosz'  
> ownership system.

In order for the user to convey to the compiler ownership, so the compiler  
could possibly make some restrictions as to what is owned and what is not,  
yes.  But that's not all, the GC would have to obey that relationship by  
not cleaning up owned resources.  We don't have that, so the only  
reasonable choice is to make *NO* restrictions.

Another solution that has been mentioned before is to declare a member  
class instance as scope, which could mean that the actual data for the  
class is allocated in the same block as the class that owns the  
reference.  Then the owner destructor can choose to deallocate  
deterministically the owned object.  But that *still* doesn't solve the  
problem of being able to determine whether heap references are valid or  
not (it does provide a workaround).

-Steve


More information about the Digitalmars-d mailing list