Difference between revisions of "C Preprocessor"

From WikiROMS
Jump to navigationJump to search
Line 1: Line 1:
ROMS extensively uses the C preprocessor(cpp) during compilation to replace code statements,  
ROMS extensively uses the C preprocessor (cpp) during compilation to replace code statements,  
insert files into the code, and select relevant parts of the code depending on its
insert files into the code, and select relevant parts of the code depending on its
directives. There are numerous cpp options that can be activated in header files [[cppdefs.h]]
directives. There are numerous cpp options that can be activated in header files [[cppdefs.h]]
Line 14: Line 14:
# Macro substitution - this functionality is better done through statement functions or inline functions which allow the Fortran compiler to do type checking.
# Macro substitution - this functionality is better done through statement functions or inline functions which allow the Fortran compiler to do type checking.


* The <span class="blue">#undef</span> directive undefines or deactiaves symbolic names. For example:
:<span class="blue">#undef</span> <span class="red">[[DEBUGGING]]</span>
:is used during parallel debugging to turn off writing current date and cpp options in ROMS history [[NetCDF]] files.
* The <span class="blue">#include</span> directive allows one to insert the contents of another file into the source code. For example:
* The <span class="blue">#include</span> directive allows one to insert the contents of another file into the source code. For example:


:<span class="blue">#include</span> <span class="red">"[[set_bounds.h]]"</span>
:<span class="blue">#include</span> <span class="red">"[[set_bounds.h]]"</span>


:is used to insert the tile-bounds header file that computes the horizontal sub-domain indices for RHO-, U- and V-type variables.
:is used to insert the tile-bounds header file that computes the horizontal sub-domain indices of RHO-, U- and V-type variables.


* The <span class="blue">#ifdef, #endif</span> directive allows to control whether the preprocessor omits and includes part of the source code. For example:
* The <span class="blue">#ifdef, #endif</span> directive allows to control whether the preprocessor omits and includes part of the source code. For example:
Line 26: Line 32:
:<span class="blue">#endif</span>
:<span class="blue">#endif</span>


:is used to activate time profiling during execution.
:is used to activate time profiling during execution. The <span class="blue">#if defined, #endif</span> directive is equivalent.


* The <span class="blue">#ifndef, #endif</span> directive is the opposite, it is executed only when the symbol is not defined or activated. For example:
* The <span class="blue">#ifndef, #endif</span> directive is the opposite, it is executed only when the symbol is not defined or activated. For example:
Line 34: Line 40:
:<span class="blue">#endif</span>
:<span class="blue">#endif</span>


:is used to reference to the equation of state module only when the option [[TS_FIXED]] is not activated.
:is used to reference to the equation of state module only when the option [[TS_FIXED]] is not activated. The <span class="blue">#if !defined, #endif</span> directive is equivalent.


* The <span class="blue">#if <test1>, #elif <test2> #endif</span> is a more general case of the above. In this case, the tests are often of the form:
* The <span class="blue">#if <test1>, #elif <test2> #endif</span> is a more general case of the above. In this case, the tests are often of the form:
:<span class="blue">defined </span> <span class="red">[[UV_TIDES]]</span> ||<span class="blue"> defined </span><span class="red">[[SSH_TIDES]]</span>
:<span class="blue">defined </span> <span class="red">[[UV_TIDES]]</span> ||<span class="blue"> defined </span><span class="red">[[SSH_TIDES]]</span>
Here, "||" is a logical "or" while "&&" is a logical "and".
:Here, "||" is a logical "or" while "&&" is a logical "and". Notice that conditional expressions always required the <span class="blue">defined </span> syntax.

Revision as of 13:23, 1 November 2006

ROMS extensively uses the C preprocessor (cpp) during compilation to replace code statements, insert files into the code, and select relevant parts of the code depending on its directives. There are numerous cpp options that can be activated in header files cppdefs.h and globaldefs.h.

Cpp is in the ANSI C standard, but that version isn't quite right for preprocessing of Fortran. We therefore use the -traditional flag with the Gnu cpp and similar flags with others.

Preprocessor Directives:

  • The #define directive comes in three flavors:
  1. Turning on a logical switch:
    #define UV_TIDES
    will turn on tidal forcing in the barotropic momentum equations.
  2. String substitution - the preprocessor will replace the symbolic name with the specified text everywhere in the code. For example:
    #define PRIVATE_2D_SCRATCH_ARRAY Istr-3:Iend+3,Jstr-3:Jend+3
    is used to set the dimensions of private, automatic 2D arrays.
  3. Macro substitution - this functionality is better done through statement functions or inline functions which allow the Fortran compiler to do type checking.
  • The #undef directive undefines or deactiaves symbolic names. For example:
#undef DEBUGGING
is used during parallel debugging to turn off writing current date and cpp options in ROMS history NetCDF files.
  • The #include directive allows one to insert the contents of another file into the source code. For example:
#include "set_bounds.h"
is used to insert the tile-bounds header file that computes the horizontal sub-domain indices of RHO-, U- and V-type variables.
  • The #ifdef, #endif directive allows to control whether the preprocessor omits and includes part of the source code. For example:
#ifdef PROFILE
CALL wclock_on (ng, iNLM, 13)
#endif
is used to activate time profiling during execution. The #if defined, #endif directive is equivalent.
  • The #ifndef, #endif directive is the opposite, it is executed only when the symbol is not defined or activated. For example:
#ifndef TS_FIXED
USE rho_eos_mod, ONLY: rho_eos
#endif
is used to reference to the equation of state module only when the option TS_FIXED is not activated. The #if !defined, #endif directive is equivalent.
  • The #if <test1>, #elif <test2> #endif is a more general case of the above. In this case, the tests are often of the form:
defined UV_TIDES || defined SSH_TIDES
Here, "||" is a logical "or" while "&&" is a logical "and". Notice that conditional expressions always required the defined syntax.