Re: [dev] [st] crash on font resize (patch inside)

From: Rian Hunter <rian+suckless-dev_AT_thelig.ht>
Date: Sat, 21 Feb 2015 03:09:16 -0800

On Feb 16, 2015, at 1:23 PM, k0ga_AT_shike2.com wrote:
>> I think the base assumptions programmers have about pointers is
>> different from integers. Pointers with null values are universally
>> known to be special and a case that should be checked for. With
>> integers, it's not obvious what the valid range is supposed to be, in
>> many cases 0 is okay. For stateful integers, it's tedious and
>> error-prone to force the programmer to re-infer what valid state is.
>> Without this knowledge its less clear who the perpetrator of the bug
>> is.
>
> I think a SIGFPE signal is a very clear error, and if you see it happens
> in a division I don't understand what other thing can generate it.

Not to beat a dead horse but this actually is an important point in programming to me so I have passion in communicating it.

The SIGFPE makes it clear there is a bug but what's less clear is what code caused the bug. For example, there could be two possibilities:

1. The function that originally generated the zero value was correct and expected that divisions by that variable when it was zero would be checked for or otherwise avoided.

2. The function that generated the zero value was incorrect and broke an invariant where that variable was never supposed to have a value of zero in the first place.

When you aren't the primary author of the software in question and you want to fix the bug, it's not clear what the original intent was and what right solution is (and this is the simplest case!). If you are the primary author, your original intent is clear to you and the fix is obvious. In a more efficient world, the fix would be obvious to everyone. That is possible if you unambiguously encode the original high-level intent in the source code.

It's subtle but I write:

    assert(foo->bar != 0);
    int quux = baz / foo->bar;

My intention isn't to promote redundant assertions, it's my machine-parseable way of saying "foo->bar should never be zero so whoever sets it to zero is buggy." I fully acknowledge that that isn't the obvious interpretation, which is why I suggested the comment option.

To draw a parallel, imagine a world where variables had no types:

    def foo(bar, baz):
        return bar + baz

    string = "quux"
    integer = 0
    foo(string, integer)

The call to foo() will cause a runtime exception, but which argument is invalid? "+" is a valid operation for both strings and integers in that example language. Let's try it again in C:

    int foo(int a, int b) {
        return a + b;
    }

    char *string = "quux";
    int integer = 0;
    foo(string, integer);

Now it's unambiguously clear that the string variable is at fault here.

Types only get us so far and in C it's still possible to write code where the high-level intent is ambiguous in other ways (e.g. the valid range of values for a variable). This is only a problem when code isn't correct. Unfortunately, that's the common case. When the intent of the original author is unambiguously encoded in the source code, the correct fix is obvious to anyone.

It's not about blindly adding redundant comments and assertions. Reducing ambiguity of intent is the name of the game, and along with types, comments and assertions are tools that can help us in that goal.

Thank you for reading.
Received on Sat Feb 21 2015 - 12:09:16 CET

This archive was generated by hypermail 2.3.0 : Sat Feb 21 2015 - 12:12:12 CET