(Thanks to Timothy Prince for the important comments)

 Preprocessors are programs that transform the source code BEFORE 
 compilation. The strange name stems from the fact that compilers
 are sometimes called language processors, so it is natural to call
 such programs preprocessors.

 Pre-processors execute "pre-processor commands" imbedded in the text, 
 and so must have a way to recognize what part of the text is a command
 and what should be "data" to be transformed. 

 One method is using special character combinations and/or putting 
 the commands at special places e.g. the C pre-processor looks for 
 '#' at the first column, RDBPRE looks for '_&RDB_&'.

 Another method is shifting the responsibility to the user, he 
 shouldn't use in his program strings that the pre-processor may 
 consider as commands. 

 Typical pre-processor commands
 Preprocessors can replace every occurrence of some string in the
 program with another pre-determined string, expand MACRO calls,
 include files etc.

 FORTRAN's statement-functions are a kind of macros!
 FORTRAN compilers can do some of the things that are usually done 
 by pre-processors. FORTRAN compiles each procedure separately, 
 and the pre-processing is also done separately for each procedure. 

 When doing such "local" pre-processing there is not much use for
 dumb string replacements, the PARAMETER statement performs this
 function in a better way. 

 Macro expansions on the other hand are still useful, as the
 following example will show:

      REAL		MATRIX(10, 10), TRSH
C     ------------------------------------------------------------------
C     ------------------------------------------------------------------
      NOQUAD(M,N) =	((MATRIX(M,N)     .LT. TRSH)  .AND.
     *			 (MATRIX(M,N+1)   .LT. TRSH)  .AND.
     *			 (MATRIX(M+1,N)   .LT. TRSH)  .AND.
     *			 (MATRIX(M+1,N+1) .LT. TRSH))
C     ==================================================================
      IF (NOQUAD(I,J+2) .OR. NOQUAD(I,J-2) .OR. 
     *    NOQUAD(I-2,J) .OR. NOQUAD(I+2,J)) THEN

 Without the statement-function NOQUAD this code fragment would 
 have been a real monster. By the way, it is part of a program
 that computes (rather badly) the fractal dimension of unspecified 
 number of geometric figures embedded in MATRIX.

 Note that the compiler will process statement-functions correctly
 even if a direct substitution would have made the line longer than
 72 columns. A non-FORTRAN oriented preprocessor (e.g. cpp) wouldn't
 generate in this case the required continuation-lines. 

 Possible uses
 A good preprocessor is a useful tool, e.g. you can define a constant 
 with an appropriate value at the beginning of the source file and 
 all the occurrences of the constant will be replaced by the value.

 Such an ability is useful because the FORTRAN compiler compiles each 
 procedure separately, and a constant that is used in several routines
 has to be redefined by each, which is a very unmodular practice.

 Like many other FORTRAN 77 problems this was solved in Fortran 90.

 C Pre-Processor (cpp)
 There are a lot of preprocessors for FORTRAN, when they are not 
 available you can use the C pre-processor:

    $ CC/DECC/PREPROCESS_ONLY=New-name  Source-file     (VMS)

 On most UNIX implementations, the FORTRAN compiler automatically 
 processes files with extension '.F' (e.g. myprog.F) with the help of
 the C pre-processor, see your compiler documentation (or 'man page').

 RATional FORtran (ratfor)
 ratfor is more than just a pre-processor, it translates a C-like
 extension of FORTRAN to ugly FORTRAN 77.

 There is a pretty-printing version.  For g77 it uses DOWHILE()...ENDDO,
 CYCLE and EXIT so it can eliminate most label targets even from
 existing code.  As a result, its indenting feature is indispensable.  

 The standard ratfor is more f66 than f77 although it is able to pass 
 much f77 through.  It requires another preprocessor (written by
 Timothy Prince) to be able to accept nearly all reasonable f77.

 m4 pre-processor

 KAP (Kuck & Associates Pre-processor ?)
 KAP is an optimizing pre-processor specially designed for a certain 
 compiler/machine combination, it does various transformations on the
 source code (introduces temporary variables etc) in anticipation of
 the code generation and optimizations done by the native compiler.

 KAP's preprocessor is an integral part of HP's Fortran compiling system, 
 and, if used with thorough application of directives, achieves typically 
 a 10% performance improvement on computational intensive work.  To do 
 this requires a lot of work profiling and examining the quality of code 
 generated by the preprocessor.  One of the problems is lack of task 
 division between preprocessor and core compiler, with both of them doing 
 loop unrolling and the like.  HP provides partial documentation on KAP.

 SGI has adopted KAP "technology" as part of their compiler, with most of 
 the pre-processing features  integrated into the main compiler.  Their 
 compiler also relies to some extent on directives, which are mostly 
 undocumented but resemble the HP ones.  Contacting Kuck Associates in 
 the hope of getting some documentation so that they could be given more 
 favorable treatment, have got only a few unkept promises.  

 Timothy Prince have written quite a bit of stuff about how to use the 
 directives, what kind of code to try to generate, but it should be noted
 that the vendors make no promises of continuity in their products.

 Experimental evaluation of FORTRAN and C with and without Kuck Fortran 
 pre-processor on the HP was performed by Timothy Prince.  He says that
 sometimes it is possible to achieve better performance with KAP and C 
 than with FORTRAN; and KAP with manual intervention is more effective 
 with C than with a good FORTRAN compiler. It is possible to make scripts 
 which usually allow the KAP code to be processed by f2c.  

Return to contents page