class C { public: this() { } ~this() { assert (0); } } void main() { C c = new C; } Upon destruction, it throws: core.exception.InvalidMemoryOperationError Which is very vague / incorrectly describes the problem. The documentation also does not mention throwing exceptions is forbidden in destructors (or are they not?). For debugging purposes I do like to assert some stuff in the destructor though...
Is this a bug or is it not allowed to assert in a destructor? I ran into this while running the druntime tests on Android/x86, was very annoying as the assert in core.sync.semaphore was swallowed up by the InvalidMemoryOperationError so I didn't know where it was actually coming from till I stuck printfs everywhere. If the assert shouldn't be allowed, druntime and possibly other D code needs to be cleaned up to get rid of any asserts in destructors.
The current GC does not support allocation during destruction (quality of implementation issue.) When the assert fails and tries to allocate it causes an invalid memory operation error.
(In reply to safety0ff.bugz from comment #2) > The current GC does not support allocation during destruction (quality of > implementation issue.) > When the assert fails and tries to allocate it causes an invalid memory > operation error. Yeah, I know what's happening, which I wrote about in github, the question is how the people who build D plan on resolving it. It doesn't help when druntime itself is asserting in its destructors, if this hasn't worked in a long time. Should we be taking all asserts out of destructors?
The real problem is that assert(0) is attempting to allocate.
*** Issue 15705 has been marked as a duplicate of this issue. ***
The offending code: https://github.com/dlang/druntime/blob/f94e816c1dd229cbb133085a6fc41d1bd6d45594/src/core/exception.d#L417-L449 Andrei suggests using a thread local static object to throw.
https://github.com/dlang/druntime/pull/1710
Given that assert(0) is intended to crash the program, wouldn't it also be reasonable to just allocate using stdc's malloc, or an OS-specific syscall, and not worry about explicitly freeing the memory? It's just going to get freed by the OS when the process terminates an instant later, anyway...
Fixed in https://github.com/dlang/druntime/pull/3476