RFC: Change what assert does on error
Dukc
ajieskola at gmail.com
Tue Jul 8 10:39:46 UTC 2025
On Tuesday, 8 July 2025 at 07:47:30 UTC, Richard (Rikki) Andrew
Cattermole wrote:
> Long story short there is no nothrow specific optimizations
> taking place.
>
Wrong! There are, like Dennis wrote:
> Agreed, but that's covered: they are both lowered to finally
> blocks, so they're treated the same, and no-one is suggesting
> to change that. Just look at the `-vcg-ast` output of this:
>
> ```D
> void start() nothrow;
> void finish() nothrow;
>
> void normal() {
> start();
> finish();
> }
>
> struct Finisher { ~this() {finish();} }
> void destructor() {
> Finisher f;
> start();
> }
>
> void scopeguard() {
> scope(exit) finish();
> start();
> }
>
> void finallyblock() {
> try {
> start();
> } finally { finish(); }
> }
> ```
>
> When removing `nothrow` from `start`, you'll see finally blocks
> in all function except (normal), but with `nothrow`, they are
> all essentially the same as `normal()`: two consecutive
> function calls.
This means that the three latter functions execute `finish()` on
unrecoverable error from `start()` if it is designated throwing,
but not if it's `nothrow`.
My suggestion would make it so that the functions aren't executed
in either case. You would have to do
```D
try start();
catch(Throwable){}
finally finish();
```
instead, as you might want to do already if you wish the
`nothrow` analysis to not matter.
> The unwinder has no knowledge of Error vs Exception, let alone
> a differentiation when running the cleanup handler. Nor does
> the cleanup handler know what the exception is. That would
> require converting finally statements to a catch all which will
> have implications.
I'm assuming such a conversion is done somewhere at the compiler
anyway. After all, the finally block is essentially higher level
functionality on top of `catch`. `try a(); finally b();` is
pretty much the same as
```D
Throwable temp;
try a();
catch (Throwable th) temp = th;
try b();
catch (Throwable th)
{ // Not sure how exception chaining really works but it'd be
done here
th.next = temp;
temp = th;
}
if(temp) throw temp;
```
More information about the Digitalmars-d
mailing list