Since initialisation order is undefined, throwing in a static constructor can end up not having a stack trace (the runtime isn't initialised yet), or probably worse (the GC insn't initialised yet). Also, there's nothing a user can actually do to recover since it happens before their program even technically begins. Even logging the exception is a bad idea because, again, initialisation (or the lack thereof).
I've been bitten by this and have made all my static constructors nothrow ever since, and I don't think there's any utility in ones that do.
Comment #1 by bugzilla — 2023-06-06T06:07:29Z
Sounds good to me.
Comment #2 by razvan.nitu1305 — 2023-06-13T10:07:52Z
Would make sense to apply the same constraints for static destructors? Actually, I think that that would make sense for constructors and destructors in general.
Comment #3 by dlang-bot — 2023-06-13T10:41:04Z
@RazvanN7 created dlang/dmd pull request #15318 "Fic Issue 23973 - static constructors should have to be nothrow" mentioning this issue:
- Fic Issue 23973 - static constructors should have to be nothrow
https://github.com/dlang/dmd/pull/15318
Comment #4 by issues.dlang — 2023-07-13T18:45:42Z
(In reply to RazvanN from comment #2)
> Would make sense to apply the same constraints for static destructors?
> Actually, I think that that would make sense for constructors and
> destructors in general.
Constructors in general are a very different issue from static constructors. Throwing from constructors on types is an extremely normal thing to do. Without that, you're often forced to do two step initialization in order to be able to tell the caller that the arguments are invalid. Disallowing throwing from normal constructors would very much be an anti-pattern.
It _might_ make sense to require that destructors on types be nothrow, but I'm not sure. C++ went and made noexcept the default for destructors, and their standard library doesn't allow destructors to throw exceptions, but IIRC, some projects actually do it. So, as I understand it, the C++ community considers it something that should generally be avoided but not necessarily something that should absolutely never be done. So, I think that we'd have to look at the situation very carefully before disallowing it in D.
Regardless, the question of static constructors and destructors and nothrow is very different from non-static ones, and the issues that Atila brought up with static constructors do not apply to regular constructors at all outside of them being called from static constructors - and those issues then apply to any code that would throw an exception from within a static constructor.
Comment #5 by robert.schadek — 2024-12-13T19:29:33Z