                          THE C PREPROCESSOR


                            Matthew Probert

                           Servile  Software


C allows for commands to the compiler to be included in the source 
code. These commands are then called preprocessor commands and are 
defined by the ANSI standard to be; 

    #if
    #ifdef
    #ifndef
    #else
    #elif
    #include
    #define
    #undef
    #line
    #error
    #pragma

All preprocessor commands start with a hash symbol, "#", and must be 
on a line on their own (although comments may follow). 


#define:

The #define command specifies an identifier and a string that the 
compiler will substitute every time it comes accross the identifier 
within that source code module. For example; 

#define FALSE 0
#define TRUE !FALSE

The compiler will replace any subsequent occurence of 'FALSE' with '0' 
and any subsequent occurence of 'TRUE' with '!0'. The substitution 
does NOT take place if the compiler finds that the identifier is 
enclosed by quotation marks, so 

    printf("TRUE");

would NOT be replaced, but

    printf("%d",FALSE);

would be.

The #define command also can be used to define macros that may include 
parameters. The parameters are best enclosed in parenthesis to ensure 
that correct substitution occurs. 

This example declares a macro 'larger()' that accepts two parameters 
and returns the larger of the two; 

#include <stdio.h>

#define larger(a,b)    (a > b) ? (a) : (b)

int main()
{
    printf("\n%d is largest",larger(5,7));

}

#error:

The #error command causes the compiler to stop compilation and to 
display the text following the #error command. For example; 

#error REACHED MODULE B

will cause the compiler to stop compilation and display;

    REACHED MODULE B


#include:

The #include command tells the compiler to read the contents of 
another source file. The name of the source file must be enclosed 
either by quotes or by angular brackets thus; 

    #include "module2.c"
    #include <stdio.h>

Generally, if the file name is enclosed in angular brackets, then the 
compiler will search for the file in a directory defined in the 
compiler's setup. Whereas if the file name is enclosed in quotes then 
the compiler will look for the file in the current directory. 

#if, #else, #elif, #endif

The #if set of commands provide conditional compilation around the 
general form; 

    #if constant_expression
        statements
    #else
        statements
    #endif

#elif stands for '#else if' and follows the form;

    #if expression
        statements
    #elif expression
        statements
    #endif


#ifdef, #ifndef:

These two commands stand for '#if defined' and '#if not defined' 
respectively and follow the general form; 

    #ifdef macro_name
        statements
    #else
        statements
    #endif

    #ifndef macro_name
        statements
    #else
        statements
    #endif

where 'macro_name' is an identifier declared by a #define statement. 


#undef:

Undefines a macro previously defined by #define.

#line:

Changes the compiler declared global variables __LINE__ and __FILE__. 
The general form of #line is; 

    #line number "filename"

where number is inserted into the variable '__LINE__' and 'filename' 
is assigned to '__FILE__'. 

#pragma:

This command is used to give compiler specific commands to the 
compiler. The compiler's manual should give you full details of any 
valid options to go with the particular implementation of #pragma that 
it supports. 

