Publications
of Jon Jagger
jon@jaggersoft.com
Appeared in CVu 9.3, March 1997

{ yourself }
#include

Good books on C have long extolled the virtues of declaring a function before using it. The usual way to declare a function is of course to #include its header. For example, before using printf() you #include <stdio.h>. However it's not uncommon to see explicit function declarations right in the middle of function definitions. For example:
int business(int accu, int men)    
{
    int snafu(int);
    ...
    return snafu(accu + men);
}
You should not declare functions like this. One reason is that you're creating duplicate declarations. If seven source files all do this, and the signature of snafu() changes, you'll have to edit all seven source files. Much better to have a single declaration of snafu() in snafu.h and then do this:
#include "snafu.h"
...
int business(int accu, int men)    
{
    ...
    return snafu(accu + men);
}
That's not the only reason though. Changes can bite you in much subtler ways. Suppose that snafu() is used in a program that needs speeding up, and profiling shows snafu() to be a bottleneck. Further, snafu() is amenable to the classic trade-off, space for time, and converts easily to a macro-lookup-table:
extern int _snafu_table[256];
#define snafu(val)  (_snafu_table[(val) & 0xFF])    
Now the code that read:
int business(int accu, int men)
{
    int snafu(int);
    return snafu(accu + men);
}
could easily be turned (by the pre-processor) into:
int business(int accu, int men)
{
    /* { yourself } */
    int (_snafu_table[(int) & 0xFF]);
    return (_snafu_table[(accu + men) & 0xFF]);    
}
and you'll then spend a good while tracking down the reason for the cryptic error message that the compiler generates. For example:
    Error YOURSELF.C 7: 
      must take address of a memory location    
where line 7 as you see it is:
    int snafu(int);    
There is a lesson here. If you are faced with a truly unfathomable compiler error message, remember that what the compiler sees is not your source code, but your source code after it's passed through the pre-processor. In these situations, consider running the compiler on already pre-processed source code. That way you can be absolutely sure that what you see is what the compiler sees.

That's all for now.
Cheers
Jon Jagger
jon@jaggersoft.com