TDPL: Manual invocation of destructor

Steven Schveighoffer schveiguy at yahoo.com
Tue Aug 10 09:35:10 PDT 2010


On Tue, 10 Aug 2010 11:44:06 -0400, Michel Fortin  
<michel.fortin at michelf.com> wrote:

> On 2010-08-10 11:12:32 -0400, "Steven Schveighoffer"  
> <schveiguy at yahoo.com> said:
>
>> On Tue, 10 Aug 2010 10:48:06 -0400, Michel Fortin   
>> <michel.fortin at michelf.com> wrote:
>>
>>> On 2010-08-10 10:19:25 -0400, "Steven Schveighoffer"   
>>> <schveiguy at yahoo.com> said:
>>>
>>>> On Tue, 10 Aug 2010 10:11:21 -0400, Michel Fortin    
>>>> <michel.fortin at michelf.com> wrote:
>>>>
>>>>> On 2010-08-10 08:11:21 -0400, "Steven Schveighoffer"    
>>>>> <schveiguy at yahoo.com> said:
>>>>>
>>>>>> Undefined, undefined, undefined :)
>>>>>  So we agree on that. That's exactly what I was trying to prove to    
>>>>> Andrei. Using clear() can break program invariants, break the type    
>>>>> system (immutable members) and so on, even though I admit it can  
>>>>> be   useful at times.
>>>>>  **** So why give it a so innocuous-looking name such as "clear" !!   
>>>>> ****
>>>>  I think that book has shipped.
>>>  That's not really an answer to the question. The answer I expected  
>>> was  more that it seemed innocuous at the time, even though now it  
>>> appears  more harmful. To me it's the C++ copy constructor all over  
>>> again...
>>>  Can we really not fix it before every one start using it? In other   
>>> words, which is worse: having something in the book deprecated just a   
>>> few months after publication? or having hundreds of programers using   
>>> clear() thinking it is innocuous?
>>  I guess I don't agree that it's badly named, or I don't really care  
>> what  it's named.  Clear sounds fine to me.  I use clear to clear out  
>> the data  in a collection, seems about the same.
>
> But is using the collection after calling clear() undefined behaviour or  
> not? Please make up your mind.

It's not the same function, just the same name.  Though I can see how it  
might be confusing:

container.clear(); // ok to reuse container
clear(container); // not ok to reuse.

But hopefully syntax highlighting can help make this distinction.  It was  
kind of nice that delete was a keyword, at least you couldn't confuse it  
with anything else.

> Seriously, if you're using "clear" to mean "empty that collection" at  
> some place and using "clear" to mean "wipe this object's data, I assert  
> no one will use it anymore" at others, then you've conflated two totally  
> different concepts. The first one is something pretty safe to do, the  
> later requires a lot more care, especially since it can break the type  
> system and bypasses protection attributes (immutable and private members  
> are wiped out too).

Well, we have what we have.  I don't think clear is such a bad name for  
either.  The time to lobby for a different name is probably over, but  
that's up to Walter/Andrei.  I don't really feel as strongly about the  
name as you do.

>>> At the very least I'd like to have a way to disable it for certain   
>>> classes (by throwing an exception when you try).
>>  Hm... do you have a good use case?
>
> Catching bugs early. Calling clear() on any object you share through the  
> D/Objective-C bridge will most likely result in a crash later if the  
> Objective-C side still holds a reference to it somewhere, or if you try  
> to use the object again. The bridge has some expectations about the  
> lifetime of the objects it manages, you shouldn't be allowed to break  
> those with an innocuous-looking function.

Again, clear doesn't scream out "use me on everything!" It's a dangerous  
function and should be treated as such.  This seems solvable via  
documentation.  I'd rather have a compile-time solution than a runtime  
solution if at all.  Are Objective-C bindings structs or classes?  If they  
are structs, we may be able to have clear obey some sort of enum, although  
that seems like an ugly solution.

Anyone who's learned C and C++ knows that you use the destruction method  
that matches with the construction method.  This is kind of the same  
thing, you wouldn't expect someone to allocate an Objective-C resource via  
some non-D-standard function, and then use a D-standard function to  
deallocate.  I think the programmer has a responsibility to obey the rules  
of allocation/deallocation.

> I would assume the same applies to QtD. In fact, any program that wants  
> to protect invariants that go beyond the scope of a single object might  
> want to disable clear().
>
> So not all objects should be clearable.

Sure, but the question is, do we care?  Is it enough to just say "Don't  
clear these objects!" in the documentation?

-Steve


More information about the Digitalmars-d mailing list