For a source file to be preprocessed automatically, it must have an uppercase extension, either .F (for a file in fixed source form) or .F90 (for a file in free source form). Files with these suffixes are preprocessed automatically by the Fortran preprocessor.
To specify preprocessing of source files with other extensions, including lowercase ones, use the -cpp, -E, -ftpp, or -P options to the f90 command.
You can alter the source code through source preprocessing directives. These directives are fully explained in “Directives”. The directives must be used according to the following rules:
Do not attempt macro substitution in Fortran comments. This will cause macros beginning with a C in column 1 (in fixed source form) not to be substituted.
When the Fortran preprocessor is used, you must specify -macro_expand on the f90(1) command line if you want to enable macro expansion outside of preprocessor directive lines.
Do not use source preprocessor (#) directives within multiline compiler directives.
You cannot include a source file that contains an #if directive without a balancing #endif directive within the same file.
The #if directive includes the #ifdef and #ifndef directives.
If a directive is too long for one source line, the backslash character (\) is used to continue the directive on successive lines. Successive lines of the directive can begin in any column (up to the column limit of 132).
The backslash character (\) can appear in any location within a directive in which whitespace can occur. A backslash character ( \) in a comment is treated as a comment character. It is not recognized as signaling continuation.
Every directive begins with the pound character ( #), and the pound character (#) must be in column 1.
Blank and tab (HT) characters can appear between the pound character (#) and the directive keyword.
You cannot write form feed (FF) or vertical tab (VT) characters to separate tokens on a directive line. That is, if a source preprocessing line spans lines, it must be continued by using a backslash character ( \).
Blanks are significant, so the use of spaces within a source preprocessing directive is independent of the source form of the file. The fields of a source preprocessing directive must be separated by blank or tab (HT) characters.
Because source preprocessing directives are independent of source form, a directive can be up to 132 columns on a single source line.
Any directive text that extends past column 132 is ignored. The directive text is truncated, which is likely to produce parsing errors or unexpected results. If a directive is too long to fit on a single line, you can continue the line by using the backslash character (\). It cannot be continued using standard Fortran continuation methods.
Any user-specified identifier that is used in a directive must follow Fortran rules for identifier formation. There are two exceptions to this rule:
The first character in the name can be an underscore character (_).
Although Fortran rules state that only the first 31 characters of identifiers are significant, to the source preprocessor, the first 132 characters are significant.
Source preprocessing identifier names are case sensitive.
Numeric literal constants must be integer literal constants or real literal constants, as defined for Fortran.
Comments written in the style of the C language, beginning with /* and ending with */, can appear anywhere within a source preprocessing directive in which blanks or tabs can appear. The comment, however, must begin and end on a single source line.
The blanks shown in the syntax descriptions of the source preprocessing directives are significant. The tab character (HT) can be used in place of a blank. Multiple blanks can appear wherever a single blank appears in a syntax description.
The following sections describe the source preprocessing directives.
The #include directive directs the system to use the content of a file or directory. Just as with the INCLUDE line processing defined by the Fortran standard, an #include directive effectively replaces that directive line with the content of filename. This directive has the following formats:
#include "filename" #include <filename>
A file or directory to be used.
In the first form, if filename does not begin with a slash (/) character, the system searches for the named file, first in the directory of the file containing the #include directive, then in the sequence of directories specified by the -I option(s) on the f90(1) command line, and then the standard (default) sequence. If filename begins with a slash (/) character, it is used as is and is assumed to be the full path to the file.
The second form directs the search to begin in the sequence of directories specified by the -I option(s) on the f90(1) command line and then search the standard (default) sequence.
The Fortran standard prohibits recursion in INCLUDE files, so recursion is also prohibited in the #include form.
The #include directives can be nested.
When the compiler is invoked to do only source preprocessing, not compilation, text will be included by #include directives but not by Fortran INCLUDE lines.
The #define directive lets you declare a source preprocessing variable and associate a token string with the variable. It also allows you to define a function-like macro. This directive has the following formats:
#define identifier value #define identifier(dummy_arg_list) value
The first format defines an object-like macro (also called a source preprocessing variable), and the second defines a function-like macro. In the second format, the left parenthesis that begins the dummy_arg_list must immediately follow the identifier, with no intervening white space.
Specifies the name of the variable or macro being defined.
Specifies a list of dummy argument identifiers.
Specifies the value as a sequence of tokens. The value can be continued onto more than one line using backslash (\) characters.
If a preprocessor identifier appears in a subsequent #define directive without being the subject of an intervening #undef directive, and the value in the second #define directive is different from the value in the first #define directive, then the preprocessor issues a warning message about the redefinition. The second directive's value is used. For more information on the #undef directive, see “#undef Directive”.
When an object-like macro's identifier is encountered as a token in the source file, it is replaced with the value specified in the macro's definition. This is referred to as an invocation of the macro. By default, tokens are not processed in Fortran source code. They are recognized only when used in other source preprocessing directives.
The invocation of a function-like macro is more complicated. It consists of the macro's identifier, immediately followed by a left parenthesis with no intervening white space, then a list of actual arguments separated by commas, and finally a terminating right parenthesis. There must be the same number of actual arguments in the invocation as there are dummy arguments in the #define directive. Each actual argument must be balanced in terms of any internal parentheses. The invocation is replaced with the value given in the macro's definition, with each occurrence of any dummy argument in the definition replaced with the corresponding actual argument in the invocation.
The following two examples must be compiled with -macro_expand specified on the f90(1) command line:
The following program prints Hello, world. when compiled and run:
PROGRAM P #define GREETING 'Hello, world.' PRINT *, GREETING END PROGRAM P
The following program prints Hello, Hello, world. when compiled and run:
PROGRAM P #define GREETING(str1, str2) str1, str1, str2 PRINT *, GREETING('Hello, ', 'world.') END PROGRAM P
The #undef directive sets the definition state of identifier to an undefined value. If identifier is not currently defined, the #undef directive has no effect. This directive has the following format:
The null directive simply consists of the pound character (#) in column 1 with no significant characters following it. That is, the remainder of the line is typically blank or is a source preprocessing comment. This directive is generally used for spacing out other directive lines.
Conditional directives cause lines of code to either be produced by the source preprocessor or to be skipped. The conditional directives within a source file form if-groups. An if-group begins with an #if, #ifdef, or #ifndef directive, followed by lines of source code that you may or may not want skipped. Several similarities exist between the Fortran IF construct and if-groups:
Just as with an IF construct, any of the blocks of source statements in an if-group can be empty.
For example, you can write the following directives:
#if MIN_VALUE == 1 #else ... #endif
Determining which group of source lines (if any) to compile in an if-group is essentially the same as the Fortran determination of which block of an IF construct should be executed.
An expression. The values in expression must be integer literal constants or previously defined preprocessor variables. The expression is an integer constant expression as defined by the C language standard. All the operators in the expression are C operators, not Fortran operators. The expression is evaluated according to C language rules, not Fortran expression evaluation rules.
Note that unlike the Fortran IF construct and IF statement logical expressions, the expression in an #if directive need not be enclosed in parentheses.
The #if expression can also contain the unary defined operator, which can be used in either of the following formats:
defined identifier defined(identifier)
When the defined subexpression is evaluated, the value is 1 if identifier is currently defined, and 0 if it is not.
All currently defined source preprocessing variables in expression, except those that are operands of defined unary operators, are replaced with their values. During this evaluation, all source preprocessing variables that are undefined evaluate to 0.
Note that the following two directive forms are not equivalent:
In the first case, the condition is true if X has a nonzero value. In the second case, the condition is true only if X has been defined (has been given a value that could be 0).
This directive has the following format:
The #ifdef directive is equivalent to either of the following two directives:
#if defined identifier
This directive is equivalent to either of the following two directives:
#if ! defined identifier
#if ! defined(identifier)
Macros that are based on the host machine
Macros that are based on IRIX system targets
Defined when abi is set to N32 or 64. Its value is the instruction set architecture. For example, _ABIN32=2 is set when -n32 is specified on the f90(1) command line; _ABI64=3 is set when -64 is specified on the f90(1) command line.
For information on the f90(1) command line, see the f90(1) man page.
Defined as the compiler version. For example, for the MIPSpro 7.2.1 release it is set as follows: _COMPILER_VERSION=721.
The leading characters in the second form consist of 2 consecutive underscores.
Set to the instruction set architecture, either 3 or 4. The leading characters consist of 2 consecutive underscores.
Set to the instruction set architecture, either 3 or 4.
Set to the instruction set architecture, as follows: _MIPS_SIM=_ABIN32 when -n32 is specified on the f90(1) command line; _MIPS_SIM=_ABI64 when -64 is specified on the f90 (1) command line.
The leading characters consist of 2 consecutive underscores.