RFC: Change what assert does on error
Adam D. Ruppe
destructionator at gmail.com
Tue Jul 8 20:37:55 UTC 2025
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.
> ```D
> mutex.lock();
> arr[i]++;
> mutex.unlock();
> ```
>
> Instead of this:
>
> ```D
> 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.
More information about the Digitalmars-d
mailing list