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