Idomatic way to guarantee to run destructor?

Ali Çehreli acehreli at yahoo.com
Mon May 4 16:33:27 UTC 2020


On 5/4/20 2:47 AM, Olivier Pisano wrote:
> On Monday, 4 May 2020 at 09:20:06 UTC, Ali Çehreli wrote:
>> On 4/30/20 10:04 AM, Ben Jones wrote:> On Thursday, 30 April 2020 at 
>> 16:55:36 UTC, Robert M. Münch wrote:
>>
>> > I think you want to use scope rather than auto which will put
>> the class
>> > on the stack and call its destructor:
>> > https://dlang.org/spec/attribute.html#scope
>>
>> That is correct about calling the destructor but the object would 
>> still be allocated with 'new', hence be on the heap. There is also 
>> library feature 'scoped', which places the object on the stack:
>>
>>   https://dlang.org/phobos/std_typecons.html#scoped
>>
>> Ali
> 
> https://godbolt.org/z/SEVsp5
> 
> My ASM skills are pretty limited, but it seems to me that the call to 
> _d_allocclass is omitted when using scope. At least with LDC and GDC.
> 
> Am I missing something ?

I stand corrected.

'scope's running the destructor was news to me, so I tested with a 
writeln example where the messages changed order depending on whether 
'scope' was replaced with 'auto' or not:

import std.stdio;

class C {
   ~this() {
     writeln("~this");
   }
}

void foo() {
   scope c = new C();  // <-- here
}

void main() {
   foo();
   writeln("foo returned");
}

Now it's news to me that 'new' does not allocate on the heap when 
'scope' is used. I'm not sure I'm comfortable with it but that's true. 
Is this unique? Otherwise, 'new' always allocates on the heap, no?

I added the following three lines to the end of foo() too see (without 
needing to look at assembly) that the 'scope' and 'auto' class objects 
are allocated on different memory regions (by taking object addresses as 
proof :) ):

   writeln(cast(void*)c);
   auto c2 = new C();
   writeln(cast(void*)c2);

Ali



More information about the Digitalmars-d-learn mailing list