Multiple destructors and NoGC exceptions?

welkam wwwelkam at
Sat Sep 7 16:35:50 UTC 2019

Today if a struct goes out scope its destructor will be called 
(if enabled) no mater what but there are two ways a scope can be 
exited – normally and trough exception. If we want to do 
different thing when scope exits normally or trough exception D 
gives few tools for that. Try finally block and more convenient 
tool scope statement. While scope statement is good it needs to 
be written inside the scope your code is running. If you are 
writing library and you want to do different things when scope 
exits you need to ask users to write scope statements manually 
and as we know hope based programming is not a good thing. So 
here is my idea.

Scoped destructors.
In addition to normal destructor there would be added two more 
destructors ~this(failure) {} and ~this(success) {}. To use them 
you would need to disable normal destructor. If a struct has 
those destructors defined at each scope block that struct appears 
compiler would use different destructor functions depending on 
how that scope was exited. If a exception caused early scope exit 
~this(failure) destructor would be called instead of standard 
destructor. Same is true for normal scope exit.

These new destructors could be used to make that a struct would 
log some data if exception occurred making it easier to debug 
failures but more important a nogc exceptions. In D if exception 
was not caught and that triggered another exception those two 
exceptions would be linked so that when you finally catch it you 
can get access to all exceptions. This feature makes it hard to 
know the lifetime of exception so they were allocated using GC 
heap. Knowing that exceptions are linked together only if scope 
exits trough exception (scope(failure)) with scoped destructors 
we could preserve all functionality of current exceptions and not 
use GC. Since scope can be exited in two ways lets reason on what 
exception object needs to do at each exit. If its scope(failure) 
it should do nothing and let runtime to attach it to the new 
exception that was thrown. Thats easy. If exception was caught 
and handled successfully the scope would exit normally and in 
this instance we need to clean up the memory. First recursively 
deallocating all exceptions that were linked to this exception 
and then deallocating its own memory. Ofc we need to protect 
internal exception data and only provide interface that returns 
copies of internal data.

I am mostly looking forward to 3 types of feedback. 1 How 
hard/feasible to implement this feature in compiler. 2 do you see 
more usage of this feature. 3 is my nogc exception idea water 


More information about the Digitalmars-d mailing list