Comparing Exceptions and Errors

Ola Fosheim Grøstad ola.fosheim.grostad at gmail.com
Mon Jun 6 16:15:19 UTC 2022


On Monday, 6 June 2022 at 15:54:16 UTC, Steven Schveighoffer 
wrote:
> If it's an expected part of the sorting algorithm that it *may 
> fail to sort*, then that's not an Error, that's an Exception.

No, it is not expected. Let me rewrite my answer to Sebastiaan to 
fit with the sort scenario:

For instance, you may have a formally verified sort function, but 
it is too slow. So you optimize one selected bottle neck, but 
that cannot be verified, because verification is hard. That 
specific unverified softspot is guarded by an assert. The 
compiler may remove it or not.

Your shipped product fails, because the hard to read optimization 
wasn't perfect. So you trap the thrown assert and call the 
reference implementation instead.

The cool thing with actors/tasks is that you can make them as 
small and targeted and revert to fallbacks if they fail.

(Assuming 100% @safe code.)

> It says that the programmer cannot attribute exactly where this 
> went wrong because otherwise, he would have accounted for it, 
> or thrown an Exception instead (or some other mitigation).

He can make a judgement. If this happened in a safe pure function 
then it would most likely be the result of what is what meant to 
do: check that the assumptions of the algorithm holds.


> Anything from memory corruption, to faulty hardware, to bugs in 
> the code, could be the cause.

That is not what asserts check! They will be removed if the 
static analyzer is powerful enough. All the information to remove 
the assert should be in the source code.

You are asserting that *given all the constraints of the type 
system* then the assert should hold.

Memory corruption could make an assert succeed when it should 
not, because then anything can happen! It cannot catch memory 
corruption reliably because it is not excluded from optimization. 
You need something else for that, something that turns off 
optimization for all asserts.


> Exactly. Use Exceptions if it's recoverable, Errors if it's not.

This is what is not true, asserts says only something about the 
algorithm it is embedded in, it says that the algorithm makes a 
wrong assumption, and that is all. It says nothing about the 
calling environment.


> A failed assert could be because of undefined behavior. It 
> doesn't *imply* it, but it cannot be ruled out.

And a successful assert could happen because of undefined 
behaviour or optimization! If you want these types of guards then 
you need to propose a type of asserts that would be excluded from 
optimization. (which might be a good idea!)

In the case of UB anything can happen. It is up to the programmer 
to make that judgment based on the use scenario. It is a matter 
of probabilisitic calculations in relation to the use scenario of 
the application.

As I pointed out elsewhere: «reliability» has to be defined in 
terms of the use scenario by a skilled human being, not in terms 
of some kind of abstract thinking about compiler design.





More information about the Digitalmars-d-learn mailing list