From: Maher Quraan <quraan@triumf.ca>
Date: Mon, 04 Oct 1999 17:30:29 -0700
To: e614software@relay.phys.ualberta.ca
Subject: Coding Conventions
I modified the coding conventions rules according to the discussion
we had before. A couple of coding conventions were added since then.
Maher
--
==================================================================
Maher Quraan Mail:
office: Trailer A, TRIUMF TRIUMF
email: quraan@triumf.ca 4004 Wesbrook Mall
phone: (604)222-1047 ext. 6333 Vancouver, BC
fax: (604)222-1074 Canada V6T 2A3
http://www.phys.ualberta.ca/~maher/maher.html
==================================================================
1. Choose clear and descriptive variable names. Clear and descriptive
subroutine, function and module names.
It is always easier to read code that has descriptive variable names.
This allows the reader to go through the code without having to go back
to a comment line to remind themselves what the variable stands for.
The same is true for procedure names and modules.
2. Provide detailed comments throughout the code.
People with different computer skills and physics backgrounds will be
reading the code (graduate students, summer students, etc). It is important
to provide enough comments to make the code understandable to everyone.
A well-documented program would allow the reader to go through the comments
and understand the code without even being familiar with the syntax!
3. Always use implicit none to force declarations of all variables.
This allows the compiler to detect a typing error, provides a documentation
of all variables used in a subroutine, and avoids misusing a variable due to
FORTRAN defaults for variable names.
4. Modules should be used instead of common blocks and parameter files.
Modules provide greater flexibility than parameter files and common
blocks. Variable initializations inside modules as well as module
functions and subroutines allow a nicer organization of the code.
5. Modules should have a complete documentation of all variables.
Variables declared in modules should always be described inside the
module so that the reader would know where to find the documentation,
rather than having to search through the code where they are used to
find their description.
6. Subroutine, function and module names should always be specified on
the end statement.
This is a nice feature that FORTRAN 90 provides, although it was not
made mandatory to allow for backward compatibility with FORTRAN 77.
7. Control structure names should be used with all long structures that
are not likely to fit on one screen. The same should be done with do
loops.
This would improve the readability of the code since long control
structures(particularly multiply nested structures) are often hard
to follow.This applies to all "do loops", "select case", "do while",
and "if" control structures. Again, FORTRAN 90 provides the option of
naming these structures, but does not make it mandatory.
8. The "intent" attribute should be used in all functions and subroutines.
This provides a nice way of telling the reader whether a subroutine's
argument is an input, an output, or both. It also avoids mistakes such
as changing the value of an argument in a subroutine where it is
intended to be an input only. FORTRAN 90 provides this option but does
not make it mandatory.
9. Interface blocks should be supplied for all external functions/subroutines.
This allows the compiler to check that the function/subroutine is being
called properly (that all arguments match in type). If not this will
be detected at compile time, therefore avoiding possible crashes due
to improper usage of a subroutine. Interface blocks also provide a nice
documentation for the reader to be able to see what subroutines are being
called from the current subroutine and refer to their variable declarations
rather than have to open each of the files to obtain that info. FORTRAN 90
does not make this mandatory in all cases to allow for backward
compatibility with FORTRAN 77.
10.Internal (rather than external) functions and subroutines should be used
if they are only intended to be used in the subroutine that calls them.
11.Pointers should be immediately associated with a target after declaration
or nullified using the "NULLIFY" statement.
This allows the use of the intrinsic function "ASSOCIATED" to check if
the pointer is associated with a target or not. If the pointer's status
is "undefined" (neither associated with a target nor nullified) the
"ASSOCIATED" function results in an error.
12.Keyword arguments should always be used when calling any procedure
containing optional arguments (unless all arguments are used).
This avoids the confusion as to which variables are being omitted from
the call.
13.Use "STATUS=replace" rather than "STATUS=unknown" when opening a file.
"STATUS=replace" is standard FORTRAN 90 that is not implementation
dependent. If the file does not exist it is created, otherwise the
existing file is deleted and a new file is created. "STATUS=unknown",
however is implementation dependent.
14.Use whole array operations whenever possible rather than element by
element assignments. However, element by element assignment could be
more efficiency if several other calculations are needed in a do loop.
FORTRAN 90 supports a large number of array features not present in
FORTRAN 77. In particular, whole array operations are a nice feature
that makes the code more readable. Element by element assignments
through do loops should be avoided whenever possible as long as it's
not at the cost of efficiency.
15.The kind attribute should be used to specify all variables.
To make sure that the kind variable is used in a platform independent
way the intrensic functions SELECTED_INTEGER_KIND, and SELECTED_REAL_KIND
should be used to specify the precision and the range. This is already
done in the module "precisions.f90", which should be "USE"d in every module.
16.Variables will not be case sensitive.
17.Lines up to 80 characters are allowed.
Although the compiler allows for up to 132 characters, lines longer than
80 characters are inconvenient for editing and printing.
18.Variable names can have up to a max of 31 characters (standard FORTRAN 90).
19.Make sure that variable names used are not cpp reserved names (ex.
UNIX, MIPS, ALPHA, etc).
21.Always use the "ACTION" specifier in the open statement to specify if the
file is "READ" "WRITE" or "READWRITE".
This provides a nice documentation for the reader to know how the
I/O file is intended to be used, and avoids mistakes of writing
output to an input file and vice versa.
22.GOTO statements and statement labels should be avoided as much as possible,
in favor of the many nice control structures that FORTRAN 90 provides.
Redirecting the flow in a program is often confusing, and almost always
time consuming for the reader. Using a GOTO statement forces the reader to:
find the line in the code where the GOTO statement is pointing, figure
out what that section of the code is doing and how it relates to where
the GOTO statement is, and then go back and find where the GOTO statement
that transfered the flow is to continue reading the code! Contrast this
to a "cycle" or an "exit" statement in a "do loop" (for example) where
you know then and there where the flow is redirected and how it relates
to the rest of the code. "Do While" statements are another good example,
where you know immediately upon entering the loop the condition for exiting.
Short FORMATs should be included in the READ/WRITE statement. Long FORMATs,
or FORMAT statements that are used more than once should be done in a seperate
FORMAT statement, and put as close to where they are being used as possible.
23.All features of FORTRAN 77 identified as obsolescent in FORTRAN 90 should
not be used.
These features are marked for deletion in future FORTRAN standards, and
have only been kept for backward compatibility with FORTRAN 77. These
include a set of features that most programmers agree are not good
programming techniques. For a list of obsolescent features see Appendix F
in "Upgrading to FORTRAN 90" by Cooper Redwine, for example.
24.Free source format should be used. Indentations of 2 or 3 spaces should be
used for statements inside do loops, if structures etc., and nested loops.
However, only one statement per line should be used.
This is important for readability purposes. The indentation rule of (2 or 3
spaces) is consistent with emacs/xemacs defaults (i.e. emacs will do it
for you if you hit tab on that line, as long as the program name has
extension ".f90").
25.Pointer names should always end with an upper case "P".
Example: planeP, wireP.
26.Comments on seprate lines and on a statement line are allowed.
27.All modules show have "_mod.f90" appended to the name.
Example: chambers_mod.f90, hists_mod.f90.
28.Contents of all modules should be made private by using the "PRIVATE"
statement in the module. Variables and procedures that need to be accessed
from outside the module should be explicitly declared public.
Making the contents of a module private protects the variables in that
subroutine from being accessed and changed by other modules that don't need
them. It also has the advantage of blocking nested use statements, and thereby
making the module dependenicies easier to sort out.
Coding Conventions / Maher Quraan
- Created for the The Center for Subatomic Research E614 Project Projects Page.
- Created by The CoCoBoard.