ftnchek - Fortran program checker
ftnchek [ -arguments=num ] [ -array=num ] [ -[no]calltree ] [ -columns=num ] [ -common=num ] [ -[no]crossref ] [ -[no]declare ] [ -[no]division ] [ -[no]extern ] [ -[no]f77 ] [ -[no]help ] [ -[no]hollerith ] [ -include=str ] [ -[no]library ] [ -[no]list ] [ -[no]novice ] [ -output=str ] [ -[no]portability ] [ -[no]pretty ] [ -[no]project ] [ -[no]pure ] [ -[no]reference ] [ -[no]sixchar ] [ -[no]sort ] [ -[no]symtab ] [ -[no]truncation ] [ -usage=num ] [ -[no]verbose ] [ -[no]volatile ] [ -wordsize=num ] [ -wrap=num ] [ files ... ]
ftnchek (short for Fortran checker) is designed to detect certain errors in a Fortran program that a compiler usually does not. ftnchek is not primarily intended to detect syntax errors. Its purpose is to assist the user in finding semantic errors. Semantic errors are legal in the Fortran language but are wasteful or may cause incorrect operation. For example, variables which are never used may indicate some omission in the program; uninitialized variables contain garbage which may cause incorrect results to be calculated; and variables which are not declared may not have the intended type. ftnchek is intended to assist users in the debugging of their Fortran program. It is not intended to catch all syntax errors. This is the function of the compiler. Prior to using ftnchek, the user should verify that the program compiles correctly.
This document first summarizes how to invoke ftnchek. That section should be read before beginning to use ftnchek. Later sections describe ftnchek's options in more detail, give an example of its use, and explain how to interpret the output. The final sections mention the limitations and known bugs in ftnchek.
ftnchek is invoked through a command of the form:
$ ftnchek [-option -option ...] filename [filename ...]
The brackets indicate something which is optional. The brackets themselves are not actually typed. Here options are command-line switches or settings, which control the operation of the program and the amount of information that will be printed out. If no option is specified, the default action is to print error messages, warnings, and informational messages, but not the program listing or symbol tables.
Each option begins with the `-' character. (On VAX/VMS or MS-DOS systems you may use either `/' or `-'.) The options are described at greater length in the next section. ftnchek options fall into two categories: switches, which are either true or false, and settings, which have a numeric or string value. The name of a switch is prefixed by `no' to turn it off: e.g. -nopure would turn off the warnings about impure functions. The `no' prefix can also be used with numeric settings, having the effect of turning off the corresponding warnings. Only the first 3 characters of an option name (not counting the `-') need be provided.
The switches and settings which ftnchek currently recognizes are:
Set level of strictness in checking subprogram arguments. Min is 0 (no checking). Max is 3 (most checking). Default = 3.
Set level of strictness in checking array arguments of subprograms. Min is 0 (least strict). Max is 3 (most strict). Default = 3.
Print tree of subprogram call hierarchy. Default = no.
Set maximum line length to n columns. (Beyond this is ignored.) Max is 132. Default = 72.
Set level of strictness in checking COMMON blocks. Min is 0 (no checking). Max is 3 (must be identical). Default = 3.
Print cross-reference list of subprogram calls and COMMON block use. Default = no.
Print a list of all identifiers whose datatype is not explicitly declared. Default = no.
Warn wherever division is done (except division by a constant). Default = no.
Warn if external subprograms which are invoked are never defined. Default = yes.
-f77 Warn about extensions to the Fortran 77 standard. Default = no.
Print command summary. Default = no.
Warn about Hollerith constants if -portability option is in effect. Default = yes.
Define a directory to search for INCLUDE files. Cumulative.
Begin library mode: do not warn about subprograms in file that are defined but never used. Default = no.
Print source listing of program. Default = no.
Give output suitable for novice users. Default = yes.
Send output to the given file. Default is to send output to the screen. (Default filename extension is .lis).
Warn about non-portable usages. Default = no.
Give warnings for possibly misleading appearance of source code. Default = yes.
Create project file (see explanation below). Default = no.
Assume functions are pure, i.e. have no side effects. Default = yes.
Print table of subprograms referenced by each subprogram. Default = no.
List any variable names which clash at 6 characters length. Default = no.
Print list of subprograms sorted in prerequisite order. Default = no.
Print symbol table for each subprogram. Default = no.
Check for possible loss of accuracy by truncation. Default = yes.
Control warnings about unused variables, etc. Min is 0 (no checking). Max is 3 (most checking). Default = 3.
Produce full amount of output. Default = yes.
Assume COMMON blocks lose definition between activations. Default = no.
Set the default word size for numeric quantities to n bytes. Default = 4 bytes.
Set output column at which to wrap long error messages and warnings to the next line. If set to 0, turn off wrapping. Default = 79.
When more than one option is used, they should be separated by a blank space, except on systems such as VMS where options begin with slash ( / ). No blank spaces may be placed around the equals sign ( = ) in a setting. ftnchek "?" will produce a command summary listing all options and settings.
When giving a name of an input file, the extension is optional. If no extension is given, ftnchek will first look for a project file with extension .prj, and will use that if it exists. If not, then ftnchek will look for a Fortran source file with the extension .for for VMS systems, .f for UNIX systems. More than one file name can be given to ftnchek, and it will process the modules in all files as if they were in a single file.
Wildcards are allowed in the specification of filenames on the command line for the VMS and MS-DOS versions, as also of course under UNIX and any other system that performs wildcard expansion in the command processor.
If no filename is given, ftnchek will read input from the standard input.
This section provides a more detailed discussion of ftnchek command-line options. Options and filenames may be interspersed on a command line. Most options are positional: each option remains in effect from the point it is encountered until it is overridden by a later change. Thus for example, the listing may be suppressed for some files and not for others. Exceptions are: the -wordsize setting, which cannot be changed once processing of input files has started; the -arguments, -array, -calltree, -common, -crossref, -extern, -reference, -sort, and -volatile options, where the action depends only on the value of the option after the processing of input files is finished; and the -include setting, which is cumulative.
The option names in the following list are in alphabetical order.
Controls warnings about mismatches between actual and dummy subprogram arguments. (An actual argument is an argument passed to the subprogram by the caller; a dummy argument is an argument received by the subprogram.)
The meanings of the setting values are as follows:
0: turn off all such warnings.
1: warn only about different number of arguments.
2: warn only about mismatch of data type of arguments and of function itself.
3: all warnings.
Default = 3.
This setting is provided mainly to suppress warnings when you wish to use ftnchek for some other purpose than checking for errors, for example when you only want to print the call tree. It does not apply to checking invocations of intrinsic functions or statement functions.
See also: -array, -library, -usage.
Controls the degree of strictness in checking agreement between actual and dummy subprogram arguments that are arrays. The warnings controlled by this setting are for constructions that might legitimately be used by a knowledgeable programmer, but that often indicate programming errors.
The meanings of the setting values are as follows:
0: only warn about cases that are seldom intentional (see note below).
1: warn if the arguments differ in their number of dimensions, or if the actual argument is an array element while the dummy argument is a whole array.
2: warn if both arguments are arrays, but they differ in number of elements.
3: give both types of warnings.
Default = 3.
Note: A warning is always given regardless of this setting if the actual argument is an array while the dummy argument is a scalar variable, or if the actual argument is a scalar variable or expression while the dummy argument is an array. No warning is ever given if the actual argument is an array element while the dummy argument is a scalar variable. Variable-dimensioned arrays and arrays dimensioned with 1 or asterisk match any number of array elements.
See also: -arguments, -library, -usage.
Causes ftnchek to print out the call structure of the complete program in the form of a tree. The tree is printed out starting from the main program, which is listed on the first line at the left margin. Then on the following lines, each routine called by the main program is listed, indented a few spaces, followed by the subtree starting at that routine. Default = no.
If a routine is called by more than one other routine, its call subtree is printed only the first time it is encountered. Later calls give only the routine name and the notice ``(see above)''.
Note that the call tree will be incomplete if any of the input files are project files containing more than one module that were created in -library mode. See the discussion of project files below.
Technical points: Each list of routines called by a given routine is printed in alphabetical order. If multiple main programs are found, the call tree of each is printed separately. If no main program is found, a report to that effect is printed out, and the call trees of any top-level non-library routines are printed. This flag only controls the printing of the call tree: ftnchek constructs the call tree in any case because it is used to determine which library modules will be cross-checked. See the discussion of the -library flag.
See also: -crossref, -library, -reference, -sort, -symtab.
Set maximum statement length to n columns. (Beyond this is ignored.) This setting is provided to allow checking of programs which may violate the Fortran standard limit of 72 columns for the length of a statement. According to the standard, all characters past column 72 are ignored. If this setting is used when the -f77 option is in effect, a warning will be given for any lines in which characters past column 72 are processed. Max is 132. Default = 72.
This setting varies the strictness of checking of COMMON blocks.
The different levels are:
0: no checking. 1: in each declaration of a given COMMON block, corresponding memory locations (words or bytes) must agree in data type.
2: also warn if different declarations of the same block are not equal in total length.
3: corresponding variables in each declaration of a block must agree in data type and (if arrays) in size and number of dimensions.
Default = 3.
The Fortran 77 standard requires each named common block, but not blank common, to be the same length in all modules of the program. Level 3 provides an extra degree of checking to support a frequent programming practice.
See also: -library, -usage, -volatile.
Specifies that a cross-reference table be printed. This table lists each subprogram followed by a list of the routines that call it. Also prints a table listing each COMMON block followed by a list of the routines that access it. Default = no.
The cross-reference listing omits library modules that are not in the call tree of the main program. The list is alphabetized. The routines listed as using a COMMON block are those in which some variables in the block are accessed, not simply those routines that declare the block. (To find out what routines declare a COMMON block but do not use it, see the -usage flag.)
See also: -calltree, -reference, -sort, -symtab.
If this flag is set, all identifiers whose datatype is not declared in each module will be listed. This flag is useful for helping to find misspelled variable names, etc. The same listing will be given if the module contains an IMPLICIT NONE statement. Default = no.
See also: -sixchar, -usage.
This switch is provided to help users spot potential division by zero problems. If this switch is selected, every division except by a constant will be flagged. (It is assumed that the user is intelligent enough not to divide by a constant which is equal to zero!) Default = no.
See also: -portability, -truncation.
Causes ftnchek to report whether any subprograms invoked by the program are never defined, or are multiply defined. Ordinarily, if ftnchek is being run on a complete program, each subprogram other than the intrinsic functions should be defined once and only once somewhere. Turn off this switch if you just want to check a subset of files which form part of a larger complete program, or to check all at once a number of unrelated files which might each contain an unnamed main program. Subprogram arguments will still be checked for correctness. Default = yes.
See also: -library.
-f77 Use this flag to catch language extensions which violate the Fortran 77 standard. Such extensions may cause your program not to be portable. Examples include the use of underscores in variable names; variable names longer than six characters; statement lines longer than 72 characters; and nonstandard statements such as the DO ... ENDDO structure. ftnchek does not report on the use of lowercase letters. Default = no.
See also: -portability, -pretty, -wordsize.
Prints a list of all the command-line options with a short description of each along with its default value. This command is identical in function to the ``?'' argument, and is provided as a convenience for those systems in which the question mark has special meaning to the command interpreter. Default = no.
The help listing also prints the version number and patch level of ftnchek and a copyright notice.
Note: the ``default'' values printed in square brackets in the help listing are, strictly speaking, not the built-in defaults but the current values after any environment options and any command-line options preceding the -help option have been processed.
Hollerith constants (other than within FORMAT specifications) are a source of possible portability problems, so when the -portability flag is set, warnings about them will be produced. If your program uses many Hollerith constants, these warnings can obscure other more serious warnings. So you can set this flag to ``no'' to suppress the warnings about Holleriths. This flag has no effect unless the -portability flag (which is off by default) is turned on. Default = yes.
See also: -portability.
Specifies a directory to be searched for files specified by INCLUDE statements. Unlike other command-line options, this setting is cumulative; that is, if it is given more than once on the command line, all the directories so specified are placed on a list that will be searched in the same order as they are given. The order in which ftnchek searches for a file to be included is: the current directory; the directory specified by environment variable FTNCHEK_INCLUDE if any; the directories specified by any -include options; the directory specified by environment variable INCLUDE; and finally in a standard systemwide directory (/usr/include for UNIX, SYS$LIBRARY for VMS, and \include for MSDOS).
This switch is used when a number of subprograms are contained in a file, but not all of them are used by the application. Normally, ftnchek warns you if any subprograms are defined but never used. This switch will suppress these warnings. Default = no.
This switch also controls which subprogram calls and COMMON block declarations are checked. If a file is read with the -library flag in effect, the subprogram calls and COMMON declarations contained in a routine in that file will be checked only if that routine is in the main program's call tree. On the other hand, if the
See also: -arguments, -calltree, -common, -extern.
Specifies that a listing of the Fortran program is to be printed out with line numbers. If ftnchek detects an error, the error message follows the program line with a caret ( ^ ) specifying the location of the error. If no source listing was requested, ftnchek will still print out any line containing an error, to aid the user in determining where the error occurred. Default = no.
See also: -symtab, -verbose.
This flag is intended to provide more helpful output for beginners. It has two effects
(a) provides an extra message to the effect that a function that is used but not defined anywhere might be an array which the user forgot to declare in a DIMENSION statement (since the syntax of an array reference is the same as that of a function reference).
(b) modifies the form of the error messages and warnings. If the flag is turned off by -nonovice, these messages are printed in a style more resembling UNIX lint.
Default = yes.
In versions of ftnchek prior to 2.6, this option could take on various numerical values, as a way of controlling various classes of warnings. These warnings are now controlled individually by their own flags. Novice level 1 is now handled by the -array flag; level 2 has been eliminated; level 3 is equivalent now to setting
ftnchek will give warnings for a variety of non-portable usages. Examples include the use of tabs except in comments or inside strings, the use of Hollerith constants, and the equivalencing of variables of different data types. This option does not produce warnings for supported extensions to the Fortran 77 standard, which may also cause portability problems. To catch those, use the -f77 option. Default = no.
See also: -f77, -hollerith, -pretty, -wordsize.
Controls certain messages related to the appearance of the source code. These warn about things that might be deceptive to the reader. Default = yes.
The warnings controlled by this flag include such things as comments that are interspersed among the continuation lines of a statement, lack of space between a keyword and a following variable name, and statement lines containing characters past column 72.
See also: -f77, -portability.
ftnchek will create a project file from each source file that is input while this flag is in effect. The project file will be given the same name as the input file, but with the extension .f or .for replaced by .prj. (If input is from standard input, the project file is named ftnchek.prj.) Default = no.
A project file contains a summary of information from the source file, for use in checking agreement among FUNCTION, SUBROUTINE, and COMMON usages in other files. It allows incremental checking, which saves time whenever you have a large set of files containing shared subroutines, most of which seldom change. You can run ftnchek once on each file with the -project flag set, creating the project files. Usually you would also set the -library and -noextern flags at this time, to suppress messages relating to consistency with other files. Only error messages pertaining to each file by itself will be printed at this time. Thereafter, run ftnchek without these flags on all the project files together, to check consistency among the different files. All messages internal to the individual files will now be omitted. Only when a file is altered will a new project file need to be made for it.
Naturally, when the -project flag is set, ftnchek will not read project files as input.
Project files contain only information needed for checking agreement between files. This means that a project file is of no use if all modules of the complete program are contained in a single file.
A more detailed discussion is given in the section on Using Project Files.
Assume functions are ``pure'', i.e., they will not have side effects by modifying their arguments or variables in a COMMON block. When this flag is in effect, ftnchek will base its determination of set and used status of the actual arguments on the assumption that arguments passed to a function are not altered. It will also issue a warning if a function is found to modify any of its arguments or any COMMON variables. Default = yes.
When this flag is turned off, actual arguments passed to functions will be handled the same way as actual arguments passed to subroutines. This means that ftnchek will assume that arguments may be modified by the functions. No warnings will be given if a function is found to have side effects. Because stricter checking is possible if functions are assumed to be pure, you should turn this flag off only if your program actually uses functions with side effects.
Specifies that a who-calls-who table be printed. This table lists each subprogram followed by a list of the routines it calls. Default = no.
The reference list omits routines called by unused library modules. Thus it contains the same information as for the -calltree flag, namely the hierarchy of subprogram calls, but printed in a different format. This prints out a breadth-first traversal of the call tree whereas -calltree prints out a depth-first traversal. If both -calltree and -reference flags are given, only the reference form of the table will be produced.
See also: -calltree, -crossref, -library, -sort, -symtab.
One of the goals of the ftnchek program is to help users to write portable Fortran programs. One potential source of nonportability is the use of variable names that are longer than six characters. Some compilers just ignore the extra characters. This behavior could potentially lead to two different variables being considered as the same. For instance, variables named AVERAGECOST and AVERAGEPRICE are the same in the first six characters. If you wish to catch such possible conflicts, use this flag. Default = no.
Use the -f77 flag if you want to list all variables longer than six characters, not just those pairs that are the same in the first six.
See also: -f77, -portability.
Specifies that a sorted list of all modules used in the program be printed. This list is in ``prerequisite'' order, i.e. each module is printed only after all the modules from which it is called have been printed. This is also called a ``topological sort'' of the call tree. Each module is listed only once. Routines that are not in the call tree of the main program are omitted. If there are any cycles in the call graph (illegal in standard Fortran) they will be detected and diagnosed. Default = no.
See also: -calltree, -crossref, -reference, -symtab.
A symbol table will be printed out for each module, listing all identifiers mentioned in the module. This table gives the name of each variable, its datatype, and the number of dimensions for arrays. An asterisk (*) indicates that the variable has been implicitly typed, rather than being named in an explicit type declaration statement. The table also lists all subprograms invoked by the module, all COMMON blocks declared, etc. Default = no.
See also: -calltree, -crossref, -list, -reference, -sort.
Warn about possible truncation (or roundoff) errors. Most of these are related to integer arithmetic. The warnings enabled when this flag is in effect are:
(a) use of the result of integer division where a real result seems intended (namely as an exponent, or if the quotient is later converted to real);
(b) division in an integer constant expression that yields a result of zero;
(c) exponentiation of an integer by a negative integer (which yields zero unless the base integer is 1 in magnitude);
(d) use of a non-integer array subscript or DO index;
(e) conversion of any real type to integer, or conversion of a complex value to real or integer;
(f) conversion of a double precision value to single precision, or vice-versa (promotion). This applies both to real types and to complex types.
Default = yes.
Note: warnings about truncating type conversions are given only when the conversion is done automatically, e.g. by an assignment statement. If intrinsic functions such as INT are used to perform the conversion, no warning is given. Promotions of real types from single to double precision are included here because such conversions imply a possible loss of accuracy that is similar to the corresponding demotions.
See also: -portability, -wordsize.
Warn about unused or possible uninitialized variables and unused common blocks.
The meanings of the setting values are as follows:
0: no warnings.
1: warn if variables are (or may be) used before they are set. 2: warn if variables are declared or set but never used.
3: give both types of warnings.
Default = 3.
Sometimes ftnchek makes a mistake about these warnings. Usually it errs on the side of giving a warning where no problem exists, but in rare cases it may fail to warn where the problem does exist. See the section on Bugs for examples. If variables are equivalenced, the rule used by ftnchek is that a reference to any variable implies the same reference to all variables it is equivalenced to. For arrays, the rule is that a reference to any array element is treated as a reference to all elements of the array.
This setting controls warnings not only for local variables but also for variables in COMMON blocks. Level 2 also controls whether a warning is given when an entire COMMON block is unused. When checking for used-before-set errors involving COMMON variables, ftnchek does not do a thorough enough analysis of the calling sequence to know which routines are called before others. So warnings about this type of error will only be given for cases in which a variable is used in some routine but not set in any other rou
This option is on by default. Turning it off reduces the amount of output relating to normal operation, so that error messages are more apparent. This option is provided for the convenience of users who are checking large suites of files. The eliminated output includes the names of project files, and the message reporting that no syntax errors were found. (Some of this output is turned back on by the -list and -symtab options.) Default = yes.
Assume that COMMON blocks are volatile. Default = no.
Many Fortran programmers assume that variables, whether local or in COMMON, are static, i.e. that once assigned a value, they retain that value permanently until assigned a different value by the program. However, in fact the Fortran 77 Standard does not require this to be the case. Local variables may become undefined between activations of a module in which they are declared. Similarly, COMMON blocks may become undefined if no module in which they are declared is active. (The technical term for this behavior is ``automatic'', but ftnchek uses the word ``volatile'' since it is clearer to the nonspecialist.) Only COMMON blocks declared in a SAVE statement, or declared in the main program or in a block data subprogram remain defined as long as the program is running. Variables and COMMON blocks that can become undefined at some point are called volatile.
If the -volatile flag is turned on, ftnchek will warn you if it finds a volatile COMMON block. If, at the same time, the -usage setting is 1 or 3 (check used before set), ftnchek will try to check whether such a block can lose its defined status between activations of the modules where it is declared. ftnchek does not do a very good job of this: the rule used is to see whether the block is declared in two separated subtrees of the call tree. For instance, this would be the case if two modules, both called from the main program, shared a volatile COMMON block. A block can also become undefined between two successive calls of the same subprogram, but ftnchek is not smart enough to tell whether a subprogram can be called more than once, so this case is not checked for.
The -volatile flag does not affect the way ftnchek checks the usage of local variables.
See also: -common, -usage.
Specifies the default word size to be n bytes. This is the size of logical and single-precision numeric variables that are not given explicit precisions. Double-precision and complex variables will be twice this value, and double complex variables four times. Explicit precisions for non-character variables are an extension to the Fortran 77 standard, and are given by type declarations such as REAL*8 X. Default = 4 bytes.
If you want to change the built-in default value of this setting, compile ftnchek with the macro name BpW (Bytes per Word) set to the desired default value. This is not critical: the word size value does not matter for checking standard-conforming programs that do not declare explicit precisions for non-character variables or store Hollerith data in variables. This setting also does not affect the default size of character variables, which is always 1 byte. Hollerith constants also are assumed to occupy 1 byte per character.
The word size is used to determine whether truncation occurs in assignment statements, and to catch precision mismatches in subprogram argument lists and common block lists. The exact warnings that are issued will depend on the status of other flags. Under both the -portability or -nowordsize flags, any mixing of explicit with default precision objects (character expressions not included) is warned about. This applies to arithmetic expressions containing both types of objects, and to subprogram arguments and COMMON variables. Under the -truncation flag, a warning is given for assignment of an expression to a shorter variable of the same type, or for promotion of a lower precision value to higher precision in an arithmetic expression or an assignment statement.
Giving a word size of 0, or equivalently, using -nowordsize means that no default value will be assumed. Use this instead of -portability if you want to check only for those aspects of portability related to mixing default and explicit precision, for example to flag places where REAL*8 is treated as equivalent to DOUBLE PRECISION.
See also: -portability, -truncation.
Controls the wrapping of error messages. Long error messages that would run past the specified column will be broken up into separate lines between the words of the message for better readability. If turned off with -nowrap, each separate error message will be printed on one line, leaving it up to the display to wrap the message or truncate it. Default = 79.
CHANGING THE DEFAULTS
ftnchek includes a mechanism for changing the default values of all options by defining environment variables. When ftnchek starts up, it looks in its environment for any variables whose names are composed by prefixing the string FTNCHEK_ onto the uppercased version of the option name. If such a variable is found, its value is used to specify the default for the corresponding switch or setting. In the case of settings (for example, the -common strictness setting) the value of the environment variable is read as the default setting value. In the case of switches, the default switch will be taken as true or yes unless the environment variable has the value 0 or NO. Of course, command-line options will override these defaults the same way as they override the built-in defaults.
Note that the environment variable name must be constructed with the full-length option name, which must be in uppercase. For example, to make ftnchek print a source listing by default, set the environment variable FTNCHEK_LIST to 1 or YES or anything other than 0 or NO. The names FTNCHEK_LIS (not the full option name) or ftnchek_list (lower case) would not be recognized.
Here are some examples of how to set environment variables on various systems. For simplicity, all the examples set the default -list switch to YES.
1. UNIX, Bourne shell: $ FTNCHEK_LIST=YES; export FTNCHEK_LIST
2. UNIX, C shell: % setenv FTNCHEK_LIST YES
3. VAX/VMS: $ DEFINE FTNCHEK_LIST YES
4. MSDOS: $ SET FTNCHEK_LIST=YES
USING PROJECT FILES
This section contains detailed information on how to use project files most effectively, and how to avoid some pitfalls.
Ordinarily, project files should be created with the -library flag in effect. In this mode, the information saved in the project file consists of all subprogram declarations, all subprogram invocations not resolved by declarations in the same file, and one instance of each COMMON block declaration. This is the minimum amount of information needed to check agreement between files.
If the file contains more than one routine, there are some possible problems that can arise from creating the project file in library mode, because the calling hierarchy among routines defined within the file is lost. Also, if the routines in the file make use of COMMON blocks that are shared with routines in other files, there will not be enough information saved for the correct checking of set and used status of COMMON blocks and COMMON variables according to the -usage setting. Therefore if you plan to use project files when the -usage setting is nonzero (which is the default situation), and if multiple routines in one project file share COMMON blocks with routines in other files, the project files should be created with the -library flag turned off. In this mode, ftnchek saves, besides the information listed above, one invocation of each subprogram by any other subprogram in the same file, and all COMMON block declarations. This means that the project file will be larger than necessary, and that when it is read in, ftnchek may repeat some inter-module checks that it already did when the project file was created. If each project file contains only one module, there is no loss of information in creating the project files in library mode.
Because of the possible loss of information entailed by creating a project file with the -library flag in effect, whenever that project file is read in later, it will be treated as a library file regardless of the current setting of the -library flag. On the other hand, a project file created with library mode turned off can be read in later in either mode.
Here is an example of how to use the UNIX make utility to automatically create a new project file each time the corresponding source file is altered, and to check the set of files for consistency. The example assumes that a macro OBJS has been defined which lists all the names of object files to be linked together to form the complete executable program.
# tell make what a project file suffix is .SUFFIXES: .prj
# tell make how to create a .prj file from a .f file .f.prj:
ftnchek -project -noextern -library $<
# set up macro PRJS containing project filenames PRJS= $(OBJS:.o=.prj) # "make check" will check everything that has been changed. check: $(PRJS)
The following simple Fortran program illustrates the messages given by ftnchek. The program is intended to accept an array of test scores and then compute the average for the series.
C AUTHORS: MIKE MYERS AND LUCIA SPAGNUOLO C DATE: MAY 8, 1989
C SCORE -> an array of test scores C SUM -> sum of the test scores C COUNT -> counter of scores read in C I -> loop counter
REAL FUNCTION COMPAV(SCORE,COUNT)
DO 30 I = 1,COUNT
SUM = SUM + SCORE(I)
COMPAV = SUM/COUNT
C MAIN PROGRAM C
C AUTHOR: LOIS BIGBIE
C DATE: MAY 15, 1990
C MAXNOS -> maximum number of input values C NUMS -> an array of numbers C COUNT -> exact number of input values C AVG -> average returned by COMPAV C I -> loop counter C
INTEGER I, COUNT
REAL NUMS(MAXNOS), AVG
COUNT = 0
DO 80 I = 1,MAXNOS
READ (5,*,END=100) NUMS(I)
COUNT = COUNT + 1
100 AVG = COMPAV(NUMS, COUNT) END
The compiler gives no error messages when this program is compiled. Yet here is what happens when it is run:
$ run average
What happened? Why didn't the program do anything? The following is the output from ftnchek when it is used to debug the above program:
$ ftnchek -list -symtab average
FTNCHEK Version 2.7 August 1993
Warning: Variables declared but never referenced: J
Warning: Variables may be used before set: SUM
External subprograms referenced:
Warning: Variables set but never used:
0 syntax errors detected in file average.f 6 warnings issued in file average.f
Subprogram COMPAV: argument data type mismatch at position 1:
Dummy type intg in module COMPAV line 10 file average.f Actual type real in module AVENUM line 43 file average.f
According to ftnchek, the program contains variables which may be used before they are assigned an initial value, and variables which are not needed. ftnchek also warns the user that an integer quotient has been converted to a real. This may assist the user in catching an unintended roundoff error. Since the -symtab flag was given, ftnchek prints out a table containing identifiers from the local module and their corresponding datatype and number of dimensions. Finally, ftnchek warns that the function COMPAV is not used with the proper type of arguments.
With ftnchek's help, we can debug the program. We can see that there were the following errors:
1. SUM and COUNT should have been converted to real before doing the division.
2. SUM should have been initialized to 0 before entering the loop.
3. AVG was never printed out after being calculated.
4. NUMS should have been declared INTEGER instead of REAL.
We also see that I, not J, should have been declared INTEGER in function COMPAV. Also, MAXNOS was not declared as INTEGER, nor COMPAV as REAL, in program AVENUM. These are not errors, but they may indicate carelessness. As it happened, the default type of these variables coincided with the intended type.
Here is the corrected program, and its output when run:
C AUTHORS: MIKE MYERS AND LUCIA SPAGNUOLO C DATE: MAY 8, 1989
C SCORE -> an array of test scores C SUM -> sum of the test scores C COUNT -> counter of scores read in C I -> loop counter C
REAL FUNCTION COMPAV(SCORE,COUNT)
SUM = 0
DO 30 I = 1,COUNT
SUM = SUM + SCORE(I)
COMPAV = FLOAT(SUM)/FLOAT(COUNT)
C MAIN PROGRAM C
C AUTHOR: LOIS BIGBIE
C DATE: MAY 15, 1990
C MAXNOS -> maximum number of input values C NUMS -> an array of numbers C COUNT -> exact number of input values C AVG -> average returned by COMPAV C I -> loop counter C
INTEGER I, NUMS(MAXNOS), COUNT
COUNT = 0
DO 80 I = 1,MAXNOS
READ (5,*,END=100) NUMS(I)
COUNT = COUNT + 1
100 AVG = COMPAV(NUMS, COUNT) WRITE(6,*) `AVERAGE =',AVG
$ run average
AVERAGE = 81.66666
With ftnchek's help, our program is a success!
INTERPRETING THE OUTPUT
The messages given by ftnchek include not only syntax errors but also warnings and informational messages about things that are legal Fortran but that may indicate errors or carelessness. Most of these messages can be turned off by command-line options. Which option controls each message depends on the nature of the condition being warned about. See the descriptions of the command-line flags in the previous sections, and of individual messages below. Each message is prefixed with a word or phrase indicating the nature of the condition and its severity. ``Error'' means a syntax error. The simplest kind of syntax errors are typographical errors, for example unbalanced parentheses or misspelling of a keyword. This type of error is caught by the parser and appears with the description ``parse error'' or ``syntax error'' (depending on whether the parser was built using GNU bison or UNIX yacc respectively). This type of error message cannot be suppressed. Be aware that this type of error often means that ftnchek has not properly interpreted the statement where the error occurs, so that its subsequent checking operations will be compromised. You should eliminate all syntax errors before proceeding to interpret the other messages ftnchek gives.
``Warning: Nonstandard syntax'' indicates an extension to Fortran that ftnchek supports but that is not according to the Fortran 77 standard. The extensions that ftnchek accepts are described in the section on Extensions below. One example is the DO ... ENDDO construction. If a program uses these extensions, warnings will be given only if the -f77 flag is set. The default is to give no warnings.
``Warning'' in other cases means a condition that is suspicious but that may or may not be a programming error. Frequently these conditions are legal under the standard. Some are illegal but do not fall under the heading of syntax errors. Usage errors are one example. These refer to the possibility that a variable may be used before it has been assigned a value (generally an error), or that a variable is declared but never used (harmless but may indicate carelessness). The amount of checking for usage errors is controlled by the -usage flag, which is set for the maximum amount of checking by default.
Truncation warnings cover situations in which accuracy may be lost unintentionally, for example when a double precision value is assigned to a real variable. These warnings are controlled by the -truncation flag, which is on by default.
``Nonportable usage'' warns about some feature that may not be accepted by some compilers even though it is not contrary to the Fortran 77 Standard, or that may cause the program to perform differently on different platforms. For example, equivalencing real and integer variables is usually a non-portable practice. The use of extensions to the standard language is, of course, another source of non-portability, but this is handled as a separate case. To check a program for true portability, both the -portability and the -f77 flags should be used. They are both turned off by default. The -wordsize setting is provided to check only those nonportable usages that depend on a particular machine wordsize.
``Possibly misleading appearance'' is used for legal constructions that may not mean what they appear to mean at first glance. For example, Fortran is insensitive to blank space, so extraneous space within variable names or the lack of space between a keyword and a variable can convey the wrong impression to the reader. These messages can be suppressed by turning off the -pretty flag, which is on by default.
Other messages that are given after all the files are processed, and having to do with agreement between modules, do not use the word ``warning'' but generally fall into that category. Examples include type mismatches between corresponding variables in different COMMON block declarations, or between dummy and actual arguments of a subprogram. These warnings are controlled by the -common and -arguments settings respectively. By default both are set for maximum strictness of checking.
Another group of warnings about conditions that are often harmless refer to cases where the array properties of a variable passed as a subprogram argument differ between the two routines. For instance, an array element might be passed to a subroutine that expects a whole array. This is a commonly-used technique for processing single rows or columns of two-dimensional arrays. However, it could also indicate a programming error. The -array setting allows the user to adjust the degree of strictness to be used in checking this kind of agreement between actual and dummy array arguments. By default the strictness is maximum.
``Oops'' indicates a technical problem, meaning either a bug in ftnchek or that its resources have been exceeded.
The format of the error messages has been modified from previous versions for more clarity. The syntax error messages and warnings now have the filename included along with the line number and column number. ftnchek now has two different options for the appearance of these error messages. If -novice is in effect, which is the default, the messages are very similar in style to those of the previous version. (In default style, the filename is not printed in messages within the body of the program if -list is in effect.) The other style of error messages is selected by the -nonovice option. In this style, the appearance of the messages is similar to that of the UNIX lint program.
ftnchek is still blind to some kinds of syntax errors. The two most important ones are detailed checking of FORMAT statements, and almost anything to do with control of execution flow by means of IF, DO, and GOTO statements: namely correct nesting of control structures, matching of opening statements such as IF ... THEN with closing statements such as ENDIF, and the proper use of statement labels (numbers). Most compilers will catch these errors. See the section on Limitations for a more detailed discussion.
If ftnchek gives you a syntax error message when the compiler does not, it may be because your program contains an extension to standard Fortran which is accepted by the compiler but not by ftnchek. (See the section on Extensions.) On a VAX/VMS system, you can use the compiler option /STANDARD to cause the compiler to accept only standard Fortran. On most UNIX or UNIX-like systems, this can be accomplished by setting the flag -ansi. Also, consult the README file included in the ftnchek distribution for information on how to control which extensions ftnchek accepts.
Many of the messages given by ftnchek are self-explanatory. Those that need some additional explanation are listed below in alphabetical order.
Common block NAME: data type mismatch at position n
The n-th variable in the COMMON block differs in data type in two different declarations of the COMMON block. By default (-common strictness level 3), ftnchek is very picky about COMMON blocks: the variables listed in them must match exactly by data type and array dimensions. That is, the legal pair of declarations in different modules:
COMMON /COM1/ A,B
COMMON /COM1/ A(2)
will cause ftnchek to give warnings at strictness level 3. These two declarations are legal in Fortran since they both declare two real variables. At strictness level 1 or 2, no warning would be given in this example, but the warning would be given if there were a data type mismatch, for instance, if B were declared INTEGER. Controlled by -common setting.
Common block NAME has long data type following short data type Some compilers require alignment of multi-byte items so that each item begins at an address that is a multiple of the item size. Thus if a short (e.g. single-precision real) item is followed by a long (e.g. double precision real) item, the latter may not be aligned correctly. Controlled by -portability option.
Common block NAME has mixed character and non-character variables The ANSI standard requires that if any variable in a COMMON block is of type CHARACTER, then all other variables in the same COMMON block must also be of type CHARACTER. Controlled by -f77 option.
Common block NAME: varying length
For -common setting level 2, this message means that a COMMON block is declared to have different numbers of words in two different subprograms. A word is the amount of storage occupied by one integer or real variable. For -common setting level 3, it means that the two declarations have different numbers of variables, where an array of any size is considered one variable. This is not necessarily an error, but it may indicate that a variable is missing from one of the lists. Note that according to the Fortran 77 standard, it is an error for named COMMON blocks (but not blank COMMON) to differ in number of words in declarations in different modules. Given for -common setting 2 or 3.
Error: Badly formed logical/relational operator or constant
Error: Badly formed real constant
The syntax analyzer has found the start of one of the special words that begin and end with a period (e.g. .EQ.), or the start of a numeric constant, but did not succeed in finding a complete item of that kind.
Error: cannot be adjustable size in module NAME A character variable cannot be declared with a size that is an asterisk in parentheses unless it is a dummy argument, a parameter, or the name of the function defined in the module.
Error: cannot be declared in SAVE statement in module NAME Only local variables and common blocks can be declared in a SAVE statement.
Error: No path to this statement
ftnchek will detect statements which are ignored or by-passed because there is no foreseeable route to the statement. For example, an unnumbered statement (a statement without a statement label), occurring immediately after a GOTO statement, cannot possibly be executed.
Error: Parse error
This means that the parser, which analyzes the Fortran program into expressions, statements, etc., has been unable to find a valid interpretation for some portion of a statement in the program. If your compiler does not report a syntax error at the same place, the most common explanations are: (1) use of an extension to ANSI standard Fortran that is not recognized by ftnchek, or (2) the statement requires more lookahead than ftnchek uses (see section on Bugs).
NOTE: This message means that the affected statement is not interpreted. Therefore, it is possible that ftnchek's subsequent processing will be in error, if it depends on any matters affected by this statement (type declarations, etc.).
Error: Statement out of order.
ftnchek will detect statements that are out of the sequence specified for ANSI standard Fortran 77. Table 1 illustrates the allowed sequence of statements in the Fortran language. Statements which are out of order are nonetheless interpreted by ftnchek, to prevent ``cascades'' of error messages.
Identifiers which are not unique in first six chars Warns that two identifiers which are longer than 6 characters do not differ in the first 6 characters. This is for portability: they may not be considered distinct by some compilers. Controlled by -sixchar option.
Nonportable usage: argument precision may not be correct for intrinsic The precision of an argument passed to an intrinsic function may be incorrect on some computers. Issued when a numeric variable declared with explicit precision (e.g. REAL*8 X) is passed to a specific intrinsic function (e.g. DSQRT(X)). Controlled by -portability and -wordsize.
Nonportable usage: character constant/variable length exceeds 255 Some compilers do not support character strings more than 255 characters in length. Controlled by -portability.
Nonportable usage: File contains tabs
ftnchek expands tabs to be equivalent to spaces up to the next column which is a multiple of 8. Some compilers treat tabs differently, and also it is possible that files sent by electronic mail will have the tabs converted to blanks in some way. Therefore files containing tabs may not be compiled correctly after being transferred. ftnchek does not give this message if tabs only occur within comments or character constants. Controlled by -portability.
Nonportable usage: non-integer DO loop bounds
This warning is only given when the DO index and bounds are noninteger. Use of non-integer quantities in a DO statement may cause unexpected errors, or different results on different machines, due to roundoff effects. Controlled by -portability.
Possibly it is an array which was not declared This message is appended to warnings related to a function invocation or to an argument type mismatch, for which the possibility exists that what appears to be a function is actually meant to be an array. If the programmer forgot to dimension an array, references to the array will be interpreted as function invocations. This message will be suppressed if the name in question appears in an EXTERNAL or INTRINSIC statement. Controlled by the -novice option.
Possibly misleading appearance: characters past 72 columns The program is being processed with the statement field width at its standard value of 72, and some nonblank characters have been found past column 72. In this case, ftnchek is not processing the characters past column 72, and is notifying the user that the statement may not have the meaning that it appears to have. These characters might be intended by the programmer to be significant, but they will be ignored by the compiler. (A similar warning is alternatively given under the -f77 flag if the -columns setting is used to increase the statement field width.) Controlled by -pretty.
Possibly misleading appearance: Common block declared in more than one Such multiple declarations are legal and have the same effect as a continuation of the original declaration of the block. This warning is only given if the two declarations are separated by one or more intervening statements. Controlled by -pretty.
Possibly misleading appearance: Continuation follows comment or blank line ftnchek issues this warning message to alert the user that a continuation of a statement is interspersed with comments, making it easy to overlook. Controlled by -pretty.
Possibly misleading appearance: Extraneous parentheses Warns about parentheses surrounding a variable by itself in an expression. When a parenthesized variable is passed as an argument to a subprogram, it is treated as an expression, not as a variable whose value can be modified by the called routine. Controlled by
and elsewhere invokes SUBA by
ftnchek will detect the error. The reason here is that the number 2 is integer, not real. The user should have said
When checking an argument which is a subprogram, ftnchek must be able to determine whether it is a function or a subroutine. The rules used by ftnchek to do this are as follows: If the subprogram, besides being passed as an actual argument, is also invoked directly elsewhere in the same module, then its type is determined by that usage. If not, then if the name of the subprogram does not appear in an explicit type declaration, it is assumed to be a subroutine; if it is explicitly typed it is taken as a function. Therefore, subroutines passed as actual arguments need only be declared by an EXTERNAL statement in the calling module, whereas functions must also be explicitly typed in order to avoid generating this error message.
Controlled by -arguments.
Subprogram NAME: argument arrayness mismatch at position n Similar to the preceding situation, but the subprogram dummy argument differs from the corresponding actual argument in its number of dimensions or number of elements. Controlled by -array together with -arguments.
Subprogram NAME: argument mismatch at position n A character dummy argument is larger than the corresponding actual argument, or a Hollerith dummy argument is larger than the corresponding actual argument. Controlled by -arguments.
Subprogram NAME: argument usage mismatch
ftnchek detects a possible conflict between the way a subprogram uses an argument and the way in which the argument is supplied to the subprogram. The conflict can be one of two types, as outlined below.
Dummy arg is modified, Actual arg is const or expr A dummy argument is an argument as named in a SUBROUTINE or FUNCTION statement and used within the subprogram. An actual argument is an argument as passed to a subroutine or function by the caller. ftnchek is saying that a dummy argument is modified by the subprogram, implying that its value is changed in the calling module. The corresponding actual argument should not be a constant or expression, but rather a variable or array element which can be legitimately assigned to. Given for -usage setting 1 or 3.
Dummy arg used before set, Actual arg not set Here a dummy argument may be used in the subprogram before having a value assigned to it by the subprogram. The corresponding actual argument should have a value assigned to it by the caller prior to invoking the subprogram. Given for -usage setting 1 or 3.
These warnings are not affected by the -arguments setting.
Subprogram NAME invoked inconsistently
Here the mismatch is between the datatype of the subprogram itself as used and as defined. For instance, if the user declares
INTEGER FUNCTION COUNT(A)
and invokes COUNT in another module as
N = COUNT(A)
without declaring its datatype, it will default to real type, based on the first letter of its name. The calling module should have included the declaration
Given for -arguments setting 2 or 3.
Subprogram NAME: varying length argument lists: An inconsistency has been found between the number of dummy arguments (parameters) a subprogram has and the number of actual arguments given it in an invocation. ftnchek keeps track of all invocations of subprograms (CALL statements and expressions using functions) and compares them with the definitions of the subprograms elsewhere in the source code. The Fortran compiler normally does not catch this type of error. Given for -arguments setting 1 or 3.
Variable not declared. Type has been implicitly defined When printing the symbol table for a module, ftnchek will flag with an asterisk all identifiers that are not explicitly typed and will show the datatype that was assigned through implicit typing. This provides support for users who wish to declare all variables as is required in Pascal or some other languages. This message appears only when the -symtab option is in effect. Alternatively, use the
Variables set but never used
ftnchek will notify the user when a variable has been assigned a value, but the variable is not otherwise used in the program. Usually this results from an oversight. Given for -usage setting 2 or 3.
Variables used before set
This message indicates that an identifier is used to compute a value prior to its initialization. Such usage may lead to an incorrect value being computed, since its initial value is not controlled. Given for -usage setting 1 or 3.
Variables may be used before set
Similar to used before set except that ftnchek is not able to determine its status with certainty. ftnchek assumes a variable may be used before set if the first usage of the variable occurs prior in the program text to its assignment. Given for -usage setting 1 or 3.
Warning: DO index is not integer
This warning is only given when the DO bounds are integer, but the DO index is not. It may indicate a failure to declare the index to be an integer. Controlled by -truncation option.
Warning: integer quotient expr converted to real The quotient of two integers results in an integer type result, in which the fractional part is dropped. If such an integer expression involving division is later converted to a real datatype, it may be that a real type division had been intended. Controlled by
Warning: NAME not set when RETURN encountered The way that functions in Fortran return a value is by assigning the value to the name of the function. This message indicates that the function was not assigned a value before the point where a RETURN statement was found. Therefore it is possible that the function could return an undefined value.
Warning: Nonstandard syntax: adjustable size cannot be concatenated here The Fortran 77 Standard forbids concatenating character variables whose size is an asterisk in parentheses, except in an assignment
Warning: Possible division by zero
This message is printed out wherever division is done (except division by a constant). Use it to help locate a runtime division by zero problem. Controlled by -division option.
Warning: real truncated to intg
ftnchek has detected an assignment statement which has a real expression on the right, but an integer variable on the left. The fractional part of the real value will be lost. If you explicitly convert the real expression to integer using the INT or NINT intrinsic function, no warning will be printed. A similar message is printed if a double precision expression is assigned to a single precision variable, etc. Controlled by -truncation option.
Warning: subscript is not integer
Since array subscripts are normally integer quantities, the use of a non-integer expression here may signal an error. Controlled by
LIMITATIONS AND EXTENSIONS
ftnchek accepts ANSI standard Fortran-77 programs with some minor limitations and numerous common extensions.
ftnchek uses only one line of lookahead when analyzing a program into its basic syntactic elements. If a particular statement is difficult to identify, it may be handled improperly if the ambiguity is not resolved on a single line. This limitation applies to complex constants except in DATA statements, and to situations in which a variable name might be confused with a keyword. For example, if the variable name WRITE is used for an array, then a very long statement assigning a value to some element of this array could be mistaken as a WRITE statement if the equals sign is not on the same line as the word WRITE.
The dummy arguments in statement functions are treated like ordinary variables of the program. That is, their scope is the entire module, not just the statement function definition.
The checking of FORMAT statements is lax, tolerating missing separators (comma, etc.) between format descriptors in places where the Standard requires them, and allowing .d fields on descriptors that should not have them. It does warn under -f77 about nonstandard descriptor types (like O), and supported extensions.
The only checking related to control of execution flow is a warning about statements that cannot be reached because they do not have a label and they follow an unconditional transfer. There is no checking for correct nesting of DO loops or matching of opening statements such as IF ... THEN with closing statements such as ENDIF, nor the proper definition and use of statement labels. Fortunately, most compilers will catch these errors.
If a user-supplied subprogram has the same name as one of the nonstandard intrinsic functions, it must be declared in an EXTERNAL statement in any routine that invokes it. Otherwise it will be subject to the checking normally given to the intrinsic function. Since the nonstandard intrinsics are not standard, this EXTERNAL statement is not required by the Fortran 77 Standard. See the lists of supported nonstandard intrinsic functions under Extensions below.
Tabs are permitted, and translated into equivalent blanks which correspond to tab stops every 8 columns. The standard does not recognize tabs. Note that some compilers allow tabs, but treat them differently.
The VMS version treats a line with an initial tab followed by a nonzero digit as a continuation line.
Lower case characters are permitted, and are converted internally to uppercase except in character strings. The standard specifies upper case only, except in comments and strings.
Hollerith constants are permitted, in accordance with the Fortran 77 Standard, appendix C. They should not be used in expressions, or confused with datatype CHARACTER.
Statements may be longer than 72 columns provided that the setting
Variable names may contain underscores and dollar signs, which are treated the same as alphabetic letters. The default type for variables beginning with these characters is REAL. In IMPLICIT type statements specifying a range of characters, the dollar sign follows Z and is followed by underscore.
The DO ... ENDDO control structure is permitted. The syntax which is recognized is according to either of the following two forms: DO [label [,]] var = expr , expr [, expr] ...
DO [label [,]] WHILE ( expr )
where square brackets indicate optional elements.
The ACCEPT and TYPE statements (for terminal I/O) are permitted, with the same syntax as PRINT.
Statements may have any number of continuation lines. The standard allows a maximum of 19.
Inline comments, beginning with an exclamation mark, are permitted.
NAMELIST I/O is supported. The syntax is the same as in VAX/VMS or IBM Fortran.
FORMAT statements can contain a dollar sign to indicate suppression of carriage-return. An integer expression enclosed in angle brackets can be used anywhere in a FORMAT statement where the Standard allows an integer constant (except for the length of a Hollerith constant), to provide a run-time value for a repeat specification or field width.
The IMPLICIT NONE statement is supported. The meaning of this statement is that all variables must have their data types explicitly declared. Rather than flag the occurrences of such variables with syntax error messages, ftnchek waits till the end of the module, and then prints out a list of all undeclared variables, as it does for the -declare option.
Data types INTEGER, REAL, COMPLEX, and LOGICAL are allowed to have an optional precision specification in type declarations. For instance, REAL*8 means an 8-byte floating point data type. The REAL*8 datatype is not necessarily considered equivalent to DOUBLE PRECISION, depending on the -wordsize setting. The Fortran 77 standard allows a length specification only for CHARACTER data.
ftnchek supports the DOUBLE COMPLEX type specification for a complex quantity whose real and imaginary parts are double precision. Mixed-mode arithmetic involving single-precision complex with double-precision real data, prohibited under the Standard, yields a double complex result. The double complex counterparts of all the standard intrinsic functions for complex data are included:
DCMPLX DCONJG DIMAG DREAL CDABS CDSQRT CDEXP CDLOG CDSIN CDCOS ZABS ZSQRT ZEXP ZLOG ZSIN ZCOS
The following other commonly found nonstandard intrinsic functions are provided. All except EXIT are defined in MIL-STD 1753.
BTEST IAND IOR IBSET IBCLR IBITS IEOR ISHFT ISHFTC NOT EXIT
For the UNIX version of ftnchek, the following common UNIX intrinsic functions are provided:
ABORT AND GETARG GETENV GMTIME IARGC LSHIFT LTIME OR IRAND RAND RSHIFT SRAND SYSTEM TIME XOR
Note: there are two common calling sequences for RAND and IRAND: with zero arguments or with 1 argument. By default, ftnchek accepts either form. If you wish to enforce strict adherence to one form or the other, you should compile ftnchek with one of the two macros RAND_NO_ARG or RAND_ONE_ARG set.
For the VAX/VMS version of ftnchek, the following common VMS intrinsic functions are provided:
DATE ERRSNS IDATE RAN SECNDS
ftnchek permits the INCLUDE statement, which causes inclusion of the text of the given file. The syntax is INCLUDE `filename'
When compiled for VMS, ftnchek will assume a default extension of .for if no filename extension is given. Also for compatibility with VMS, the VMS version allows the qualifier /[NO]LIST following the filename, to control the listing of the included file. There is no support for including VMS text modules.
At this time, in diagnostic output relating to items contained in include files, the only information about the location of the error is its location in the include file. There is no traceback giving the parent file(s).
ftnchek accepts PARAMETER definitions that involve intrinsic functions and exponentiation by a non-integer exponent. Both of these cases are prohibited by the standard, and will be warned about if the -f77 flag is set. If an intrinsic function is a compile-time integer constant, ftnchek will evaluate it. This allows better checking if the parameter is used in declaring array sizes.
The intrinsic functions that are evaluated are:
ABS IABS DIM IDIM MAX MAX0 MIN MIN0 MOD SIGN ISIGN LEN ICHAR INDEX
The functions of integer arguments are evaluated only if the arguments are integer constant expressions. (These may involve integer constants, parameters, and evaluated intrinsic functions.) The function LEN is evaluated if its argument is an expression involving only character constants and variables whose length is not adjustable. The functions ICHAR and INDEX are evaluated only if the arguments are character constants. ftnchek gives a warning if it needs the value of some intrinsic function that is not evaluated.
Here are the changes from Version 2.6 to Version 2.7:
1. Fixed bugs: to allow statement functions with no arguments; to catch extra comma in subprogram argument lists; argument of LEN does not need to have a defined value.
2. Insensitive to blanks as per the Standard. 3. Changed behavior of options: -f77 controls warnings about statement out of order and COMMON block with mixed character and non-character data; -help option now lists patch level and copyright; -novice controls appearance of warning messages.
4. Added handling of explicit precision and double complex data type. REAL*8 is no longer synonymous with DOUBLE PRECISION, depending on the machine wordsize. Checking length agreement for character data also done properly now.
5. Checking usage status of COMMON blocks and COMMON variables.
6. Improved format of messages.
7. Support for common nonstandard intrinsic functions.
8. New options: -arguments, -crossref, -reference, -sort, -volatile,
10. Added expansion of wildcards for filenames on the command line to the VMS and MS-DOS versions.
11. Parser is generated by bison. Formerly yacc was used.
12. Made changes to allow the IBM PC version handle larger files.
Here are the changes from Version 2.5 to Version 2.6:
1. The following bugs in Version 2.5 were fixed: Overflow of large integer parameter values. Inline comment character mistaken in difficult contexts. Unnamed BLOCK DATA modules treated as main programs. DATA implied-do statements sometimes parsed incorrectly. Size of variable-dimensioned arrays sometimes calculated incorrectly. Documented bug number 1 in the previous documentation, which caused a used-before-set warning if a function modifies an argument, has been fixed. The warning is now controlled by the
3. New command-line flags added and existing flags modified for better control of error and warning reporting. Affected flags are: -array,
4. New warnings: if array subscript or DO index is non-integer; if constant value of 0 results from integer division or exponentiation; and if data type of expression in logical or arithmetic IF statement is improper. The warning of ``variable declared but not used'' is now suppressed when the declaration is in an include file. A warning is now given under the -f77 option if the standard limit of 19 continuation lines is exceeded.
ftnchek still has much room for improvement. Your feedback is appreciated. We want to know about any bugs you notice. Bugs include not only cases in which ftnchek issues an error message where no error exists, but also if ftnchek fails to issue a warning when it ought to. Note, however, that ftnchek is not intended to catch all syntax errors (see section on Limitations). Also, it is not considered a bug for a variable to be reported as used before set, if the reason is that the usage of the variable occurs prior in the text to where the variable is set. For instance, this could occur when a GOTO causes execution to loop backward to some previously skipped statements. ftnchek does not analyze the program flow, but assumes that statements occurring earlier in the text are executed before the following ones.
We especially want to know if ftnchek crashes for any reason. It is not supposed to crash, even on programs with syntax errors. Suggestions are welcomed for additional features which you would find useful. Tell us if any of ftnchek's messages are incomprehensible. Comments on the readability and accuracy of this document are also welcome.
You may also suggest support for additional extensions to the Fortran language. These will be included only if it is felt that the extensions are sufficiently widely accepted by compilers.
If you find a bug in ftnchek, first consult the list of known bugs below to see if it has already been reported. Also check the section entitled ``Limitations and Extensions'' above for restrictions that could be causing the problem. If you do not find the problem documented in either place, then send a report including
1. The operating system and CPU type on which ftnchek is running.
2. The version of ftnchek.
3. A brief description of the bug.
4. If possible, a small sample program showing the bug.
The report should be sent to either of the following addresses:
Highest priority will be given to bugs which cause ftnchek to crash. Bugs involving incorrect warnings or error messages may take longer to fix.
Certain problems that arise when checking large programs can be fixed by increasing the sizes of the data areas in ftnchek. (These problems are generally signaled by error messages beginning with ``Oops''.) The simplest way to increase the table sizes is by recompiling ftnchek with the LARGE_MACHINE macro name defined. Consult the makefile and README file for the method of doing this.
The following is a list of known bugs.
1. Bug: Used-before-set message is suppressed for any variable which is used as the loop index in an implied-do loop, even if it was in fact used before being set in some earlier statement. For example, consider J in the statement
WRITE(5,*) (A(J), J=1,10)
Here ftnchek parses the I/O expression, A(J), where J is used, before it parses the implied loop where J is set. Normally this would cause ftnchek to report a spurious used-before-set warning for J. Since this report is usually in error and occurs fairly commonly, ftnchek suppresses the warning for J altogether.
Prognosis: A future version of ftnchek is planned which will handle implied-do loops correctly.
2. Bug: Variables used (not as arguments) in statement-function subprograms do not have their usage status updated when the statement function is invoked.
Prognosis: To be fixed in a future version of ftnchek.
3. Bug: VAX version does not expand wildcards in filenames on the command line if they are followed without space by an option, e.g. ftnchek *.f/calltree would not expand the *.f. This is because VMS-style options without intervening space are not supported by the GNU shell_mung routine that is used to expand wildcards.
Prognosis: unlikely to be fixed.
ftnchek is a public-domain program. It was designed by Dr. Robert Moniot, professor at Fordham University, College at Lincoln Center. During the academic year of 1988-1989, Michael Myers and Lucia Spagnuolo developed the program to perform the variable usage checks. During the following year it was augmented by Lois Bigbie to check subprogram arguments and COMMON block declarations. Brian Downing assisted with the implementation of the INCLUDE statement. John Quinn wrote the common block usage checks. Additional features will be added as time permits. With Version 2.5, the name was changed from forchek to ftnchek, to avoid confusion with a similar program named forcheck, developed earlier at Leiden University.
We would like to thank John Amor of the University of British Columbia, Reg Clemens of the Air Force Phillips Lab in Albuquerque, Markus Draxler of the University of Stuttgart, Victor Eijkhout of the University of Tennessee at Knoxville, Greg Flint of Purdue University, Daniel P. Giesy of NASA Langley Research Center, Fritz Keinert of Iowa State University, Judah Milgram of the University of Maryland College Park, Hugh Nicholas of the Pittsburgh Supercomputing Center, Dan Severance of Yale University, Phil Sterne of Lawrence Livermore National Laboratory, Larry Weissman of the University of Washington, Warren J. Wiscombe of NASA Goddard, and especially Nelson H. F. Beebe of the University of Utah, for pointing out bugs and suggesting some improvements. We also thank Jack Dongarra for putting ftnchek into the netlib library of publicly available software, and Lee Rimar of Absoft Corporation for providing an executable version for Macintosh. The -reference feature was contributed by Gerome Emmanuel, Ecole des mines, U. Nancy (slightly modified).
INSTALLATION AND SUPPORT
The ftnchek program can be obtained by anonymous ftp from many software servers, including host research.att.com (184.108.40.206) where it is located in directory /netlib/fortran. It can also be obtained via electronic mail by sending the message: ``send ftnchek from fortran'' to the Internet address: firstname.lastname@example.org.
Installation requires a C compiler for your computer. Executable binary in ZIP format for IBM PC computers under MS-DOS is available by anonymous ftp from wuarchive.wustl.edu (220.127.116.11) where it is located in directory /mirrors/msdos/fortran, filename ftnchk27.zip. Executable binary in stuffit format for Macintosh computers is also available from the same archive, in directory /mirrors/macintosh/lang, filename ftnchk27.sit.
ftnchek has a number of fixed internal parameters that affect its operation, such as the symbol table sizes and support for various extensions and particular operating systems. They are implemented as C language macro names. If you wish to change a parameter defined by one of these macros, it is necessary to recompile ftnchek with the macro definition changed to the desired value. See the README file for a list of these macro names and instructions for defining them according to your preferences.
This document is named ftnchek.man. On UNIX systems, you can print it using the command nroff -man ftnchek.man | lpr. The distribution also includes a PostScript version of this document named ftnchek.ps which can be printed directly on any PostScript printer.
For further information and to report bugs, you may contact Dr. Robert Moniot at either of the following network addresses: