Program logic bugs vs input/environmental errors
Bruno Medeiros via Digitalmars-d
digitalmars-d at puremagic.com
Wed Nov 19 03:59:20 PST 2014
On 09/11/2014 21:33, Walter Bright wrote:
> On 11/7/2014 7:00 AM, Bruno Medeiros wrote:
>> Let me give an example:
>>
>> double sqrt(double num) {
>> assert(num >= 0);
>> ...
>>
>> With just this, then purely from a compiler/language viewpoint, if the
>> assert is
>> triggered the *language* doesn't know if the whole program is corrupted
>> (formatting the hard disk, etc.), or if the fault is localized there,
>> and an
>> error/exception can be thrown cleanly (clean in the sense that other
>> parts of
>> the program are not corrupted).
>>
>> So the language doesn't know, but the *programmer* can make a
>> reasoning in each
>> particular assert of which domains/components of the program are
>> affected by
>> that assertion failure. In the sqrt() case above, the programmer can
>> easily
>> state that the math library that sqrt is part of is not corrupted, and
>> its state
>> is not totally unknown (as in, it's not deadlocked, nor is it
>> formatting the
>> hard disk!).
>
> Making such an assumption presumes that the programmer knows the SOURCE
> of the bug. He does not. The source could be a buffer overflow, a wild
> pointer, any sort of corruption.
>
>
>> Very well then. But then we'll get to the point where enforce() will
>> become much
>> more popular than assert to check for contract conditions. assert()
>> will be
>> relegated to niche and rare situations where the program cant really
>> know how to
>> continue/recover cleanly (memory corruption for example).
>>
>> That idiom is fine with me actually - but then the documentation for
>> assert
>> should reflect that.
>
> I created this thread because it is an extremely important topic. It has
> come up again and again for my entire career.
>
> There is no such thing as knowing in advance what caused a bug, and that
> the bug is "safe" to continue from. If you know in advance what caused
> it, then it becomes expected program behavior, and is not a bug.
>
> assert() is for bug detection, detecting state that should have never
> happened. By definition you cannot know it is "safe", you cannot know
> what caused it.
>
> enforce() is for dealing with known, expected conditions.
As I mentioned before, it's not about knowing exactly what caused it,
nor knowing for sure if it is "safe" (this is an imprecise term anyways,
in this context).
It's about making an educated guess about what will provide a better
user experience when an assertion is triggered: halting the program, or
ignoring the bug and continuing the program (even if admittedly the
program will be in a buggy state).
I've already mentioned several examples of situations where I think the
later is preferable.
Just to add another one, one that I recently came across while coding,
was an assertion check that I put, which, if it where to fail, would
only cause a redundant use of memory (but no NPEs or access violations
or invalid state, etc.).
--
Bruno Medeiros
https://twitter.com/brunodomedeiros
More information about the Digitalmars-d
mailing list