Thread overview | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
April 30, 2020 Idomatic way to guarantee to run destructor? | ||||
---|---|---|---|---|
| ||||
For ressource management I mostly use this pattern, to ensure the destructor is run:
void myfunc(){
MyClass X = new MyClass(); scope(exit) X.destroy;
}
I somewhere read, this would work too:
void myfunc(){
auto MyClass X = new MyClass();
}
What does this "auto" does here? Wouldn't
void myfunc(){
auto X = new MyClass();
}
be sufficient? And would this construct guarantee that the destructor is run? And if, why does "auto" has this effect, while just using "new" doesn't guarantee to run the destructor?
--
Robert M. Münch
http://www.saphirion.com
smarter | better | faster
|
April 30, 2020 Re: Idomatic way to guarantee to run destructor? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert M. Münch | On Thursday, 30 April 2020 at 16:55:36 UTC, Robert M. Münch wrote: > For ressource management I mostly use this pattern, to ensure the destructor is run: > > void myfunc(){ > MyClass X = new MyClass(); scope(exit) X.destroy; > } > > I somewhere read, this would work too: > > void myfunc(){ > auto MyClass X = new MyClass(); > } > > What does this "auto" does here? Wouldn't > > void myfunc(){ > auto X = new MyClass(); > } > > be sufficient? And would this construct guarantee that the destructor is run? And if, why does "auto" has this effect, while just using "new" doesn't guarantee to run the destructor? 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 |
April 30, 2020 Re: Idomatic way to guarantee to run destructor? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert M. Münch | On 4/30/20 12:55 PM, Robert M. Münch wrote:
> For ressource management I mostly use this pattern, to ensure the destructor is run:
>
> void myfunc(){
> MyClass X = new MyClass(); scope(exit) X.destroy;
> }
>
> I somewhere read, this would work too:
>
> void myfunc(){
> auto MyClass X = new MyClass();
> }
>
> What does this "auto" does here? Wouldn't
>
> void myfunc(){
> auto X = new MyClass();
> }
>
> be sufficient? And would this construct guarantee that the destructor is run? And if, why does "auto" has this effect, while just using "new" doesn't guarantee to run the destructor?
No, auto is declaring that there's about to be a variable here. In actuality, auto does nothing in the first case, it just means local variable. But without the type name, the type is inferred (i.e. your second example). This does not do any automatic destruction of your class, it's still left to the GC.
You can use scope instead of auto, and it will then allocate the class on the stack, and destroy it as Ben Jones said. There is danger there, however, as it's very easy to store a class reference elsewhere, and then you have a dangling pointer.
A safer thing to do is:
auto X = new MyClass();
scope(exit) destroy(X);
This runs the destructor and makes the class instance unusable, but does not free the memory (so any remaining references, if used, will not corrupt memory).
If your concern is guaranteeing destructors are run, that's what I would pick. If in addition you want guaranteed memory cleanup, then use scope (and be careful).
-Steve
|
May 02, 2020 Re: Idomatic way to guarantee to run destructor? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Jones | On 2020-04-30 17:04:43 +0000, Ben Jones said: > 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 Yes, thanks. -- Robert M. Münch http://www.saphirion.com smarter | better | faster |
May 02, 2020 Re: Idomatic way to guarantee to run destructor? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer Attachments:
| On 2020-04-30 17:45:24 +0000, Steven Schveighoffer said: > No, auto is declaring that there's about to be a variable here. In actuality, auto does nothing in the first case, it just means local variable. But without the type name, the type is inferred (i.e. your second example). This does not do any automatic destruction of your class, it's still left to the GC. Ok, that was my understand too. As said, I found some older posts and was a bit confused... > You can use scope instead of auto, and it will then allocate the class on the stack, and destroy it as Ben Jones said. There is danger there, however, as it's very easy to store a class reference elsewhere, and then you have a dangling pointer. Ok. Can't this be combined with some "don't let the refrence escape my function" feature of D? > A safer thing to do is: > > auto X = new MyClass(); > scope(exit) destroy(X); > > This runs the destructor and makes the class instance unusable, but does not free the memory (so any remaining references, if used, will not corrupt memory). How would that help, because the class instance is now unusable anyway. So I have it around like a zombie and others might think: "Hey you look normal, let's get in contact" and then you are doomed... > If your concern is guaranteeing destructors are run, that's what I would pick. If in addition you want guaranteed memory cleanup, then use scope (and be careful). Ok, thanks. -- Robert M. Münch http://www.saphirion.com smarter | better | faster |
May 02, 2020 Re: Idomatic way to guarantee to run destructor? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert M. Münch | On 5/2/20 4:44 AM, Robert M. Münch wrote: > On 2020-04-30 17:45:24 +0000, Steven Schveighoffer said: > > You can use scope instead of auto, and it will then allocate the class on the stack, and destroy it as Ben Jones said. There is danger there, however, as it's very easy to store a class reference elsewhere, and then you have a dangling pointer. > > > Ok. Can't this be combined with some "don't let the refrence escape my function" feature of D? I don't know. perhaps dip1000 helps here. > > > A safer thing to do is: > > > auto X = new MyClass(); > > scope(exit) destroy(X); > > > This runs the destructor and makes the class instance unusable, but does not free the memory (so any remaining references, if used, will not corrupt memory). > > > How would that help, because the class instance is now unusable anyway. So I have it around like a zombie and others might think: "Hey you look normal, let's get in contact" and then you are doomed... The difference is that if you use it, you get an error and a crash. If you clean up the memory, that memory could be reallocated to something else with a completely different type, and now you have memory corruption. -Steve |
May 02, 2020 Re: Idomatic way to guarantee to run destructor? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On 2020-05-02 18:18:44 +0000, Steven Schveighoffer said: > On 5/2/20 4:44 AM, Robert M. Münch wrote: > >> How would that help, because the class instance is now unusable anyway. So I have it around like a zombie and others might think: "Hey you look normal, let's get in contact" and then you are doomed... > > The difference is that if you use it, you get an error and a crash. If you clean up the memory, that memory could be reallocated to something else with a completely different type, and now you have memory corruption. I didn't thought about the "memory is re-used" case here... And how is the instance made unusable so that a crash happens (which I prefer too!)? Does .destroy zero the memory? Just curious how the crash situation is detected. -- Robert M. Münch http://www.saphirion.com smarter | better | faster |
May 02, 2020 Re: Idomatic way to guarantee to run destructor? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert M. Münch | On 5/2/20 3:08 PM, Robert M. Münch wrote: > On 2020-05-02 18:18:44 +0000, Steven Schveighoffer said: > >> On 5/2/20 4:44 AM, Robert M. Münch wrote: >> >>> How would that help, because the class instance is now unusable anyway. So I have it around like a zombie and others might think: "Hey you look normal, let's get in contact" and then you are doomed... >> >> The difference is that if you use it, you get an error and a crash. If you clean up the memory, that memory could be reallocated to something else with a completely different type, and now you have memory corruption. > > I didn't thought about the "memory is re-used" case here... > > And how is the instance made unusable so that a crash happens (which I prefer too!)? Does .destroy zero the memory? Just curious how the crash situation is detected. > destroy sets all the values to the .init value. And it nulls the vtable pointer. So any virtual calls will crash with a segfault. non-virtual calls won't crash immediately, but generally there are few class calls that have all final calls. And even if they do go through, the .init value should be harmless in terms of memory safety. For reference, destroy calls this function on class instances (Same as GC cleanup) where p is really the class reference: https://github.com/dlang/druntime/blob/999367be8fa5d13a718d951d67c3d580ca13aef1/src/rt/lifetime.d#L1414 You can see in the finally clause, the vptr is set to null. -Steve |
May 03, 2020 Re: Idomatic way to guarantee to run destructor? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On 2020-05-02 20:43:16 +0000, Steven Schveighoffer said: > destroy sets all the values to the .init value. And it nulls the vtable pointer. Ok, that makes sense. Thanks for all the deep internal details. There is always a lot to learn. -- Robert M. Münch http://www.saphirion.com smarter | better | faster |
May 04, 2020 Re: Idomatic way to guarantee to run destructor? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Jones | 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 |
Copyright © 1999-2021 by the D Language Foundation