Calling destroy on struct pointer

Moritz Maxeiner via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Feb 25 05:14:24 PST 2017


On Saturday, 25 February 2017 at 10:44:07 UTC, Radu wrote:
> On Saturday, 25 February 2017 at 08:36:02 UTC, Ali Çehreli 
> wrote:
>> On 02/25/2017 12:17 AM, Radu wrote:
>>
>> > destroy(cc) -> does c = C.init
>> > destroy(*cc); -> calls the C dtor
>> >
>> > Is this by design? If so - how can I destroy and get the dtor
>> called
>> > without dereferencing the pointer?
>>
>> It's by design because setting a pointer to null can be 
>> considered as destroying the pointer. Dereferencing is the 
>> right way of destroying the object through the pointer.
>>
>> I had added the following warning after somebody else was 
>> burnt by this feature. :)
>>
>>   http://ddili.org/ders/d.en/memory.html#ix_memory.destroy
>>
>> Ali
>
> I think this is BAD. Why?
>
> - it is one of those WAT?? moments that brings a RTFM slap to 
> you. The defaults should not be surprising, and in this case 
> straight dangerous as it can lead to leaks.

Unfortunately, I don't think it's viable to change destroy (see 
below), it would probably be better to cover this in the dlang 
tour (if it isn't already).

> - it is not always possible to dereference the pointer, think 
> some circular structures where deref would get you one of those 
> fwd. declaration errors.

In the interest of learning, could you provide an example of such 
a case?

> - the deprecated delete will call the dtor, destroy is suppose 
> to replace delete - hence it should work the same.

AFAIK destroy isn't supposed to replace delete, since delete is 
destruction+deallocation and destroy is only destruction; and by 
that definition they cannot work the same: AFAIR multiple deletes 
are illegal (since that equals use after free), whereas destroy 
can be used on the same object as often as you want (the 
destructor will only be called the first time).

>
> In my opinion destroy should do this:
> - call dtor if the pointer type has one defined
> - nullify the pointer
>
> This is what I was expecting anyhow to happen...

This change would be backwards-incompatible and breaks user code, 
especially manual memory management:

---
struct A {}

auto a = cast (A*) malloc(A.sizeof); // Allocate
emplace(a, 42);                      // Construct

destroy(a);                          // Destruct
free(a);                             // Deallocate
---

if destroy were to already nullify a, how were one supposed to 
deallocate a?


More information about the Digitalmars-d-learn mailing list