Thread overview
Multiple destructors and NoGC exceptions?
Sep 07, 2019
welkam
Sep 07, 2019
Max Haughton
Sep 07, 2019
welkam
September 07, 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.

Uses.
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 tight.

Destroy
September 07, 2019
On Saturday, 7 September 2019 at 16:35:50 UTC, welkam wrote:
> 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.
>
> [...]

I'm m not sure if I'm reading this correctly, but are you aware of dip1008?
September 07, 2019
On Saturday, 7 September 2019 at 18:57:18 UTC, Max Haughton wrote:
> I'm m not sure if I'm reading this correctly, but are you aware of dip1008?

dip1008 solves nogc exceptions by making them reference counted. If my proposal works it would make exceptions nogc without adding extra fields or extra code to be run every time exception goes out of scope. Also scoped destructors can be used for other things