RFC: Change what assert does on error

Richard (Rikki) Andrew Cattermole richard at cattermole.co.nz
Sun Jul 6 14:04:46 UTC 2025


On 07/07/2025 1:54 AM, Dennis wrote:
> On Sunday, 6 July 2025 at 02:08:43 UTC, Jonathan M Davis wrote:
>> If an Error is such a terrible condition that we don't even
>> want the stack unwinding code to be run properly, then instead of 
>> throwing anything, the program should have just printed out a stack 
>> trace and aborted right then and there (...)
> 
> Yes! Hence the proposal in the opening thread.
> 
>> I can understand not wanting any stack unwinding code to run if an 
>> Error occurs on the theory that the condition is bad enough that 
>> there's a risk that some of what the stack unwinding code would do 
>> would make the situation worse, but IMHO, then we shouldn't even have 
>> Errors.
> 
> Yes! If it were up to me, Error was removed from D yesterday. But 
> there's push back because  users apparently rely on it, and I can't 
> figure out why. From my perspective, a distilled version of the 
> conversation here is:
> 
> Proposal: make default assert handler 'log + exit'

And then there is contracts that apparently need to catch AssertError.

Which killed that particular idea.

Its one thing to break code, its another to break a language feature.

>> That's bad! In UI applications users can't report the log when the 
>> program exits
> 
> Then use a custom assert handler?
> 
>> I do, but the compiler needs to ignore `nothrow` for it to work
> 
> What is your handler doing that it needs that?
> 
>> log + system("pause") + exit
> 
> Why does that depend on cleanup code being run?
> 
>> ...
> 
> And this is where I get nothing concrete, only that 'in principle' it's 
> more correct to run the destructors because that's what the programmer 
> intended. I find this unconvincing because we're talking about 
> unexpected error situations, appealing to 'the correct intended code 
> path according to principle' is moot because we're not in an intended 
> situation.
> 
> What would be convincing is if someone came forward with a real example 
> "this is what my destructors and assert handler do, because the cleanup 
> code was run the error log looked like XXX instead of YYY, which saved 
> me so many hours of debugging!". But alas, we're all talking about 
> vague, hypothetical scenarios which you can always create to support 
> either side.

The only way to get this is to implement the changes needed.

However we can't change the default without evidence that it is both ok 
to do and preferable.

>> And maybe we should make the behavior configurable so that programemrs 
>> can choose which they want rather than mandating that it work one way 
>> or the other
> 
> Assert failures and range errors just call a function, and you can 
> already swap that function out for whatever you want through various 
> means. The thing that currently isn't configurable is whether the 
> compiler considers that function `nothrow`.

You also can't configure how the unwinder works. It isn't just "one 
function". There are multiple implementations and its entire modules, 
and not just ones in core.

> The problem with making that an option is that this affects nothrow 
> inference, which affects mangling, which results in linker errors. In 
> general, adding more and more options like that just explodes the 
> complexity of the compiler and ruins compatibility. I'd like to avoid it 
> if we can.

Why would it effect inference?

Leave the frontend alone.

Do this in the glue layer. If flag is set and compiler flag is set to a 
specific value don't add unwinding.


More information about the Digitalmars-d mailing list