Eliminate class allocators and deallocators?

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Wed Oct 7 11:06:00 PDT 2009


Leandro Lucarella wrote:
> Andrei Alexandrescu, el  6 de octubre a las 21:42 me escribiste:
>>>>> should call a destructor but not call delete() or notify the GC
>>>>> that the memory is free.
>>>> That is correct. In particular, an object remains usable after delete.
>>> Why would you do that? What is the rationale to not notify the GC?
>> Because there may be other live references to the object.
> 
> But when using delete that's exactly what it should happen. You are hiding
> a bug if you let that happen on purpose.

That is not hiding a bug. That's even worse than Walter's crappy 
argument :o).

>>>>> You're saying that there is a problem, but you're not telling us
>>>>> what's wrong. Why the hell do you want to destroy an object
>>>>> without recycling its memory? Why does the inability to do so
>>>>> cause a problem?
>>>> The matter has been discussed quite a bit around here and in other
>>>> places. I'm not having as much time as I'd want to explain things.
>>>> In short, destroying without freeing memory avoids dangling
>>>> references and preserves memory safety without impacting on other
>>>> resources.
>>> But D is a system programming language.
>> Well it is but there are quite a few more things at stake. First, it
>> is a reality that it is often desirable to distinguish between
>> calling the destructor and reclaiming memory. D's current delete
>> continues the bad tradition started by C++ of conflating the two.
> 
> Why is a bad idea? If you are destroying an object, the object will be in
> an inconsistent state. What's the point of keeping it alive. Again, you're
> just hiding a bug; letting the bug live longer. The language should try to
> expose bugs ASAP, not delay the detection.

It is a bad idea because distinguishing between release of (expensive) 
resources from dangerous memory recycling is the correct way to obtain 
deterministic resource management within the confines of safety.

> I think is a good idea not to force the GC to free the memory immediately
> with a delete, but it should if it's easy. Other protection methods as
> using mprotect to protect the objects pages it's very desirable too,
> because you can spot an access to a inconsistent (destroyed) object as
> soon as it first happen.

(mprotect is much too coarse to be useful.) With the dispose() function 
the state of the object will be restored to default construction:

void dispose(T)(T obj) if (is(T == class) || is(typeof(*T.init))) {
    ... call destructor if any ...
    ... obliterate object with .init ...
    ... invoke default ctor if any ...
}

>>> If you wrote delete x; the
>>> language should assume you know what you're doing.
>> I think delete should be present in SafeD and if you want manual
>> memory management you should build on malloc and free.
> 
> If you want to introduce a new semantic, I think you should provide a new
> method, not change the semantic of an existent one.

Agreed. I hereby vote for deprecating delete with extreme prejudice.

> And BTW, is there any reason why this can't be implemented in the library
> instead of using an operator? Why don't you provide a "destroy()" function
> for that in Phobos?

That sounds great.

> Really, I can't see any advantages on changing the delete operator
> semantics, only problems.

I agree.

>>> If you only want to
>>> "deinitialize" an object, you can write a .destroy() method for example,
>>> and call that. I think delete have a strong established semantic to change
>>> it now, and without any gain.
>> It has a thoroughly broken and undesired semantics. It would be a step
>> forward to divorce it of that.
> 
> Why it's broken? Why it's undesired?

(See above in this message.)

> Why? Using malloc and free is a lot more trouble, you have to register the
> roots yourself for example. It's not like you do malloc() and free() and
> everything works magically. You have to have more knowledge of the GC to
> use them. Being able to manually manage the *GC* heap (if the GC support
> that, if not it can make it a NOP) is good IMHO.

We can make things a tad better with library functions, but we do need 
to have a garbage collected heap that guarantees safety.


Andrei



More information about the Digitalmars-d mailing list