On Saturday, June 03, 2017 08:17:18 Stanislav Blinov via Digitalmars-d-learn wrote: > On Saturday, 3 June 2017 at 08:01:14 UTC, Jonathan M Davis wrote: > > On Saturday, June 03, 2017 06:41:44 Stanislav Blinov via > > > > Digitalmars-d-learn wrote: > >> On Saturday, 3 June 2017 at 06:19:29 UTC, Jonathan M Davis > >> > >> wrote: > >> > looking at what rt_finalize does, I don't see why it > >> > couldn't be nothrow. So, unless I'm missing something, it > >> > seems like that would be a good enhancement. > >> > > >> > - Jonathan M Davis > >> > >> Presently, rt_finalize cannot be made nothrow, or un-made > >> @system, because "reasons": > >> http://forum.dlang.org/thread/aalafajtuhlvfirwf...@forum.dlang.org > >> > >> Fixing that would require significant changes to the runtime, > >> and probably the compiler. I don't think it qualifies as a > >> simple "enhancement" :) > > > > Well, as I said, I could be missing something, but all > > rt_finalize does is call rt_finalize2, and rt_finalize2 _is_ > > nothrow (it catches any Exceptions that are thrown by the > > destructor/finalizer). So, I have no idea why it would be the > > case that rt_finalize couldn't be nothrow, and I saw nothing in > > that thread which contradicts that, but I could have read it > > too quickly. Regardless, it's a perfectly valid enhancement > > request whether it's easy to implement or not. > > > > - Jonathan M Davis > > Whoops, my bad, I forgot it indeed swallows exceptions and does > the onFinalizeError instead. So... yep, then it seems that > rt_finalize probably should be marked nothrow too. Hmm... if > throwing in a destructor is considered a runtime error, perhaps > another valid enhancement would be to statically disallow > throwing Exceptions in destructors, i.e. *require* them be > nothrow?..
My initial reaction would be that destructors should always be nothrow, though I vaguely recall there being some reason why it was supposed to be nice that destructors in D could cleanly deal with exceptions. And remember that when we're talking about rt_finalize, we're talking about finalizers, not destructors in general. When a destructor is in a GC heap-allocated object, it's treated as a finalizer and may or may not be run (since the object may or may not be collected), whereas when a destructor is on an object that's on the stack, it's really a destructor. So, while they use the same syntax, and in the case of a struct, the same function could be either a destructor or a finalizer depending on where the struct is declared, they're not quite the same thing. And destroy muddies the water a bit, because it then explicitly calls the finalizer on a class, whereas it would normally be the GC that does it (and while calling GC-related functions in a finalizer is forbidden when called by the GC, it's fine when called via destroy, since the GC is then not in the middle of a collection). So, I don't know whether it would be reasonable to require that destructors be nothrow. Certainly, it's _more_ likely for it to be reasonable for destructors on classes to be nothrow, since classes always live on the heap (and are thus finalizers) unless you're playing games with something like std.typecons.scoped, but I'd have to study the matter quite a bit more to give a properly informed answer as to whether it would be reasonable to require that all destructors be nothrow. - Jonathan M Davis