Difference between revisions of "C Preprocessor"

From WikiROMS
Jump to navigationJump to search
Line 10: Line 10:
* The <span class="blue">#define</span> directive comes in three flavors:
* The <span class="blue">#define</span> directive comes in three flavors:


# Turning on a logical switch. For example, the following definition will activate tidal forcing in the open boundary conditions to the barotropic momentum equations: <br /><span class="blue">#define</span> <span class="red">[[UV_TIDES]]</span><br />
# Turning on a logical switch. For example, the following definition will activate tidal forcing in the open boundary conditions to the barotropic momentum equations: <br /><span class="blue">#define</span> <span class="red">[[UV_TIDES]]</span>
# String substitution. The preprocessor will replace the symbolic name with the specified text everywhere in the code. For example, the following assigment is used to set the dimensions of private, automatic 2D arrays: <br /><span class="blue">#define</span> <span class="red">PRIVATE_2D_SCRATCH_ARRAY</span> Istr-3:Iend+3,Jstr-3:Jend+3<br />
# String substitution. The preprocessor will replace the symbolic name with the specified text everywhere in the code. For example, the following assigment is used to set the dimensions of private, automatic 2D arrays: <br /><span class="blue">#define</span> <span class="red">PRIVATE_2D_SCRATCH_ARRAY</span> Istr-3:Iend+3,Jstr-3:Jend+3
# 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, the following option is used in parallel debugging to turn on/off the writing of current date and cpp options in ROMS history [[NetCDF]] files:
* The <span class="blue">#undef</span> directive undefines or deactiaves symbolic names. For example, the following option is used in parallel debugging to turn on/off the writing of current date and cpp options in ROMS history [[NetCDF]] files:<br /><span class="blue">#undef</span> <span class="red">[[DEBUGGING]]</span>


:<span class="blue">#undef</span> <span class="red">[[DEBUGGING]]</span>
* The <span class="blue">#include</span> directive allows one to insert the contents of another file into the source code. For example, the following statement is used to insert the tile-bounds header file that computes the horizontal sub-domain indices of RHO-, U- and V-type variables.<br /><span class="blue">#include</span> <span class="red">"[[set_bounds.h]]"</span>


* The <span class="blue">#include</span> directive allows one to insert the contents of another file into the source code. For example, the following statement 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 or its equivalent <span class="blue">#if defined, #endif</span> allows to control whether the preprocessor omits and includes part of the source code. For example, the following code section is used to activate time profiling during execution:<br /><span class="blue">#ifdef</span> <span class="red">[[PROFILE]]</span><br /><code>CALL wclock_on (ng, iNLM, 13)</code><br /><span class="blue">#endif</span>


:<span class="blue">#include</span> <span class="red">"[[set_bounds.h]]"</span>
* The <span class="blue">#ifndef, #endif</span> directive or its equivalent <span class="blue">#if !defined, #endif</span> is the opposite. It is executed only when the symbol is not defined or activated. For example, the following statement is used to reference to the equation of state module only when the option [[TS_FIXED]] is not activated.<br /><span class="blue">#ifndef</span> <span class="red">[[TS_FIXED]]</span><br /><code>USE rho_eos_mod, ONLY: rho_eos</code><br /><span class="blue">#endif</span>


* The <span class="blue">#ifdef, #endif</span> directive or its equivalent <span class="blue">#if defined, #endif</span> allows to control whether the preprocessor omits and includes part of the source code. For example, the following code section is used to activate time profiling during execution:
* 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:<br /><span class="blue">defined </span> <span class="red">[[UV_TIDES]]</span> ||<span class="blue"> defined </span><span class="red">[[SSH_TIDES]]</span><br />Here, <span class="blue">||</span> is a logical '''or''' while <span class="blue">&&</span> is a logical '''and'''. Notice that conditional expressions require the <span class="blue">defined </span> syntax.
:<span class="blue">#ifdef</span> <span class="red">[[PROFILE]]</span>
::CALL wclock_on (ng, iNLM, 13)
:<span class="blue">#endif</span>
 
* The <span class="blue">#ifndef, #endif</span> directive or its equivalent <span class="blue">#if !defined, #endif</span> is the opposite. It is executed only when the symbol is not defined or activated. For example, the following statement is used to reference to the equation of state module only when the option [[TS_FIXED]] is not activated.
 
:<span class="blue">#ifndef</span> <span class="red">[[TS_FIXED]]</span>
::USE rho_eos_mod, ONLY: rho_eos
:<span class="blue">#endif</span>
 
* 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>
:Here, "||" is a logical "or" while "&&" is a logical "and". Notice that conditional expressions require the <span class="blue">defined </span> syntax.

Revision as of 17:03, 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. For example, the following definition will activate tidal forcing in the open boundary conditions to the barotropic momentum equations:
    #define UV_TIDES
  2. String substitution. The preprocessor will replace the symbolic name with the specified text everywhere in the code. For example, the following assigment is used to set the dimensions of private, automatic 2D arrays:
    #define PRIVATE_2D_SCRATCH_ARRAY Istr-3:Iend+3,Jstr-3:Jend+3
  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, the following option is used in parallel debugging to turn on/off the writing of current date and cpp options in ROMS history NetCDF files:
    #undef DEBUGGING
  • The #include directive allows one to insert the contents of another file into the source code. For example, the following statement is used to insert the tile-bounds header file that computes the horizontal sub-domain indices of RHO-, U- and V-type variables.
    #include "set_bounds.h"
  • The #ifdef, #endif directive or its equivalent #if defined, #endif allows to control whether the preprocessor omits and includes part of the source code. For example, the following code section is used to activate time profiling during execution:
    #ifdef PROFILE
    CALL wclock_on (ng, iNLM, 13)
    #endif
  • The #ifndef, #endif directive or its equivalent #if !defined, #endif is the opposite. It is executed only when the symbol is not defined or activated. For example, the following statement is used to reference to the equation of state module only when the option TS_FIXED is not activated.
    #ifndef TS_FIXED
    USE rho_eos_mod, ONLY: rho_eos
    #endif
  • 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 require the defined syntax.