On Tuesday, 8 July 2025 at 14:05:25 UTC, Dennis wrote:
> So I take it opend changed that, being okay with the breaking change?
opend reverted dmd's change of behavior introduced around 2018. Prior to then, dmd ran the finally blocks in all cases, then they changed it to "optimize" nothrow functions.
Now, I can't call this a regression per se, since the documentation said you can't expect the finally blocks to be run on Errors already even before that change, but this was a breaking change in practice - and not a simple compile error if you happened to combine certain features, it is a silent change to runtime behavior, not running code you wrote in only certain circumstances. Quite spooky.
Only if you dogmatically stick to the ideology that catching errors is unacceptable - despite the potential real world benefits of catching it, and the fact it does work just fine most the time even in upstream today (and historically, did in all cases) - can you justify this skipping of code as an optimization rather than a silent wrong-code compiler bug.
> Because @safe constructors of structs containing fields with @system destructors will now raise a safety error even with nothrow
.
I've never encountered this, perhaps because upstream also worked this same way for many years, including through most the active development period of druntime, phobos, and arsd doesn't really concern itself with @safe nothrow attribute spam.
But if this did cause a compile error.... I'd prefer that to a silent runtime change, at least we'd be alerted to the change in behavior instead of being left debugging a puzzling situation with very little available information.
> mutex.lock();
arr[i]++;
mutex.unlock();
Instead of this:
mutex.lock();
scope(exit) mutex.unlock();
arr[i]++;
Like here, if the RangeError is thrown and the mutex remains locked with the first code sample, ok, you can understand the exception was thrown on line 2, so line 3 didn't run. Not pleasant when it happens to you, but you'll at least understand what happened.
But with the second sample, it'd take a bit, not much since it being an Error instead of Exception would jump out pretty quickly, but a bit of language lawyering to understand why the mutex is still locked in upstream D - normally, scope(exit)
is a good practice for writing exception safe code.
> While I can't say I have the numbers to prove that its performance is important to me, I currently like the idea that scope(exit)/destructors are a zero-cost abstraction when Exceptions are absent.
For what its worth, I kinda like the idea too, it did pain me a little to see the codegen bloat back up a lil when reverting that change. But....
> > Correctness trumps minor performance improvements.
yup.