On Saturday, 6 March 2021 at 04:29:41 UTC, Jack wrote:

Now about the behavior of a static destructor, like static ~this() { } is this guaranteed to be run?

Yes. Some perspective:

1. During program execution, class/struct destructors on stack-allocated instances are invoked when the instances go out of scope.

2. During program execution, class/struct destructors on GC-allocated instances are only called when the GC determines the instances are no longer referenced AND it needs to reclaim memory. There is no way to know when or if this will happen during the program's execution. Short-lived programs may never need to reclaim memory, so the destructors may never be called. The longer a program runs, and the more it allocates from the GC heap, the more likely it is that a given object's destructor will be called during execution since the GC will need to reclaim memory more often. This is a consequence of relying on the GC to manage memory.

3. After the main function exits, the runtime will invoke all module destructors. They do not belong to any class or struct instance, nor are they managed by the GC. They will always execute.

4. After module destructors are invoked, the GC will begin its shutdown. By default, it will invoke the destructors on every class/struct instance for which it hasn't. This can be disabled via a command-line argument for DRuntime.

So with the current implementation, all GC-managed class and struct destructors will end up being called at some point. But the spec does not require the GC to invoke destructors during shutdown--that's an implementation detail. Moreover, since the person executing the program can turn that behavior off via a command-line argument, you can't rely on the default behavior anyway. So that's why the documentation says that class and struct destructors are not guaranteed to be invoked by the GC.

Reply via email to