Use_cpp Memo for using the C preprocessor in the ABINIT package. Copyright (C) 1999-2006 ABINIT group (XG,LSI,DCA) This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt . For the initials of contributors, see ~abinit/doc/developers/contributors . Note : the C preprocessor is used at a rudimentary level, but at least it seems to be sufficiently portable at that level !! 1. Usage at compile time ------------------------ Suppose the c preprocessor's location is /lib/cpp A file file.f will be preprocessed to file_cpp.f by the following command : /lib/cpp file.f > file_cpp.f The file file_cpp.f is a fortran file without cpp additions, thus appropriate for compilation. It is the one for which the compiler indicates a line number in case of error. (Usually, there is however little problem in using directly file.f for the understanding of the compiler messages) Additional options to be used : /lib/cpp -P -C -Ddefined1 -Ddefined2 file.f > file_cpp.f The option -P is for preprocessing only The option -C keeps "comments" in, which keeps // intact for fortran character string concatenation The "defined" arguments defined1 or defined2 (or more if needed) are often used for the C preprocessor to know which version of the code it must generate. Example of defined arguments : MPI (for the parallel version) ibm (for the IBM version) P6 (for the PPro version) FFTW (for the fftw non multithreaded version) FFTWTHREADS ( for the fftw multithreaded version) CACHE=1024 (for cache optimization) ... 2. Usage in the body of the routines. ------------------------------------- A. Version maintenance using if ... elif ... endif construct In the body of the routine, appearance of #if defined IBM ... codeibm ... #elif defined SGI ... codesgi ... #endif when preprocessed with the -DIBM argument, will give ... codeibm ... The similar effect is true with the -DSGI argument Other information about this construct : 1) It seems that the #else instruction has a bug on the SGI, so avoid it. 2) The logical operators are as follows : ! for logical negation || for logical or && for logical and For example #if defined IBM || defined SGI ... #elif !defined P6 ... #endif 3) On HP machines, cpp directives are only recognized if # is the first character of the line; any number of blanks or tabs are allowed between the # and the directive. e.g. # ifdef HP ... # endif B. Replacement of variable at preprocess time Appearance of #define FNLEN 132 at the beginning of the routine will cause replacements of the occurences of FNLEN by 132 in the body of the routine. 3. WARNINGS ----------- 3.1. Do not use comments at the end of a C-processed line, like the following : #define FNLEN 132 /* THIS is a forbidden comment */ It is NOT portable. Use instead !THIS is an allowed comment #define FNLEN 132 3.2. CPP does not recognize Fortran comments sign. Inside comments, you MUST use ' or " signs in pairs. !It's forbidden !It''s allowed 3.3. Inside CPP sections, // might be treated as the end of the code to be removed on each line, despite being the concatenation sign in FORTRAN (this behaviour can be avoided on some machines, if the flag -traditional is used). Thus, avoid concatenating strings inside CPP sections. (Note easy, sometimes ...)