To make sure that programs are re-entrant, some precautions have to be taken. That is, the programmer has to be disciplined about the use of global variables.
In a reentrant program, the same piece of code can be executed by many jobs. This sharing of code has implications. c68 compiles global variables to have a fixed position in the code. So, if the code is shared by several jobs, thhat variable will also be shared between the programs which use that code.
In short, you should not use global variables, except for shared data structures (like for example the font cache in PROforma). This normally means that mutual exclusion has to be used when accessing the data.
To aid in catching the errors which occur, we often use two mechanisms. For starters, a lot of functions calls in a program look like this
{ Error err; err=...function call...; if (err) return err; }
To make such calls a little easier to read we often use a special macro.
#define catch(x) do { if (err=(x)) return err; } while (0) { Error err; catch( ...function call... ); }
This will make programs in which many of the calls can fail a lot easier to read. Please note that the else in the macro definition allows this macro to be used in if-then-else clauses without worrying about which if the else belongs to (so that the macro is completely transparant).
The catch macro seems to be a bit strange with the do .. while construct. This is included only to have normal parsing rules for the semicolon. It is optimized out of your code by the compiler (fortunately).
Another tip on catching errors is to split functions to make sure that everything can be cleaned up easily when an error occurs. For example, the following program opens a file and reads the first line and a byte of that file (not very useful, its just an example).
#include "err_h" #include "io_h" #define catch(x) if (err=(x)) return err; else #define MAXLINELEN 60 Error HandleFile(Channel channel); Error ReadFile(char directory, char filename) { Error err; Channel channel; catch( IOOpenPath(filename, OPEN_READ, directory, &channel) ) err=HandleFile(channel); IOClose(channel); return err; } Error HandleFile(Channel channel) { Error err; char ch, line[MAXLINELEN]; catch( IOGet(channel, &ch) ); catch( IOGetString(channel, line, MAXLINELEN) ); return err; }