www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Alternative destructors, do/should we have them?

reply Dukc <ajieskola gmail.com> writes:
D does not have default constructors for structs, but I have 
thought that this might get around the problem:

struct MallocedPtr()
{   void* location;
     ~this()
     {   import core.stdc.stdlib;
         assert(location != null);
         free(location.ptr);
     }
}

Unlike a destructor which has a runtime check whether it's 
initialized, this has no performance cost over a C++-style 
default-initialized struct. I think "hand grenade RAII" is a 
perfect name for this idiom, because like a hand grenade, this 
struct asserts it is set somewhere else after initialization 
before it's destructor runs.

But there is a problem. If you use std.algorithm.move to give a 
hand grenade to a function, it initializes another hand grenade 
for the calling function. I didn't come up with any way to defuse 
the initialized grenade without runtime cost.

Granted, a runtime check at destructor is unlikely to be a major 
performance hit for any normal application, but D is a systems 
language, right? Do you have any ideas to get around this? If 
not, should we in your opinion have an ability to define an 
alternative destructor which runs only when explicitly requested?
Jul 05 2018
next sibling parent reply Andrea Fontana <nospam example.com> writes:
On Thursday, 5 July 2018 at 10:57:51 UTC, Dukc wrote:
 If not, should we in your opinion have an ability to define an 
 alternative destructor which runs only when explicitly 
 requested?
What does "when explicity requested" mean?
Jul 05 2018
parent Dukc <ajieskola gmail.com> writes:
On Thursday, 5 July 2018 at 15:58:14 UTC, Andrea Fontana wrote:
 On Thursday, 5 July 2018 at 10:57:51 UTC, Dukc wrote:
 If not, should we in your opinion have an ability to define an 
 alternative destructor which runs only when explicitly 
 requested?
What does "when explicity requested" mean?
That the alternative destructor runs only when you ask it to. There would be some way to say before an end of a block, return statement, break statement ect that you want the alternative destructor to be applied to the struct. The normal destructor would not run when an alternative one is used, but would run otherwise. In fact, in this case it would be enough to elide the destructor somehow.
Jul 05 2018
prev sibling parent reply Atila Neves <atila.neves gmail.com> writes:
On Thursday, 5 July 2018 at 10:57:51 UTC, Dukc wrote:
 D does not have default constructors for structs, but I have 
 thought that this might get around the problem:

 [...]
You already have that capability: struct HandGrenade { void* ptr; void destroy() { import core.stdc.stdlib: free; free(ptr); } } This isn't a great example since it's perfectly fine to pass null to core.stdc.stdlib.free. Atila
Jul 05 2018
parent Dukc <ajieskola gmail.com> writes:
On Thursday, 5 July 2018 at 16:12:08 UTC, Atila Neves wrote:
 On Thursday, 5 July 2018 at 10:57:51 UTC, Dukc wrote:
 D does not have default constructors for structs, but I have 
 thought that this might get around the problem:

 [...]
You already have that capability: struct HandGrenade { void* ptr; void destroy() { import core.stdc.stdlib: free; free(ptr); } } This isn't a great example since it's perfectly fine to pass null to core.stdc.stdlib.free. Atila
On Thursday, 5 July 2018 at 16:12:08 UTC, Atila Neves wrote:
 This isn't a great example since it's perfectly fine to pass 
 null to core.stdc.stdlib.free.

 Atila
You're right. Well, It could be some custom allocation table that does not check for such things: struct HandGrenade { void* ptr; ~this() { foreach ( ref _byte; cast(ubyte[]) ptr[0 .. memoryTable.assumeSorted.upperBound(ptr).front - ptr] ) _byte = 0; } }
Jul 05 2018