Avoiding fundamental mistakes when programming

 

Dear Moritz, I am writing this for you, as you are developing your first C-programs. No matter what programming language you are using in the context of imperative, object-orientated or functional programming. Here is something you may find useful.

First I want to draw your attention to something you learned in mathematics lessons at school around the 8th or 9th class. You were taught, that a function – something like

f(x)= 1/x

has a Domain of a Function ( [De] Definitionsmenge ) and a Codomain ( [De] Wertemenge).

You were taught, that you can only use values which are element of the Domain of the function to compute a result and that the result must be an element of that Codomain.

In the example given above it’s “forbidden” to use the value 0 (zero) for x.

When you look at functions, procedures or methods in programming, it’s pretty much the same. Here I am starting with functions.

When you write down a function – for whatever purpose – you usually intend to pass a value to it and in return receive a result.

Of course you could code the above function f(x) in C, C++, Ada or Fortran (or whatever) and before you execute the function you need to write a little code that makes sure that the value you pass to this function is not zero.

And after that function returned its result, you need to check, if that result is within the limits of what you want to deal with.

Basically it will look like this:

double my_q(double d1, double d2)
{
    return ( d1 / d2 );
}
int main (void)
{
    int v1=3, v2=0;

    if ( v2 == 0) {
        (void)fprintf(stderr, "division by zero not allowed\n");
        return(-1);
    }
    (void) printf("my result -> %.5f\n", my_q(v1, v2));
    return(0);
}

(in a UNIX/Linux environment just type “make <program>.c” in this simple case and the program will be compiled)

yael@never-mind:~/tc$ make qq
cc     qq.c   -o qq
yael@never-mind:~ ls -l
total 16
-rwxrwxr-x. 1 yael yael 8627 Oct 26 15:32 qq
-rw-rw-r--. 1 yael yael  295 Oct 26 15:32 qq.c
yael@never-mind:~/tc$ ./qq
division by zero not allowed
yael@never-mind:~/tc$

The example above never yields a valid result and the function my_q (); which is the purpose of this example.

Basically this is not about teaching C-programming. It’s an attempt to show that you need to define the valid ranges of your variables and you need to check them before and after a function-call. In the above example you may not be interested in values outside a particular corridor of permissible deviation respectively you may want to invoke some corrective action in order to get back into that corridor.

With a procedure it’s basically the same. There are just more variables to check. When you make complex calls (call by reference) and pass the address of a complete structure or array, it may be important to run a comprehensive sanity check of all of your values before you invoke your procedure.  Defining the domains of your procedure (which can be many) may be a tedious work, but it pays of.