My FORmula TRANslating System Standard
These notes can be useful in writing Fortran programs that are clean, portable, and modern. Beyond these qualities, it is also nice to look at
code that is easy to read as well as maintain. Standardization is important in computer programming because it promotes compatibility, interoperability, and repeatability.
Use free source formIndent two spaces after the line continuation character
&. You can put
&anywhere, but I like to put them in column 132—I just think it makes the code look nicer.
Replace DO WHILE statements
DO ... IF() EXIT ... END DOfor better control; need opposite relational operators, e.g.,
>. Be careful about over-counting.
Use generic intrinsic functionsAlways use generic intrinsic functions—e.g.,
SQRT, etc.—for mathematical operations. This rightly gives the compiler the task of how to handle their arguments (real, complex, etc.).
Use white space between mathematical operatorsPut spaces between the mathematical operators
Use lowercase edit descriptorsEdit descriptors for
WRITEstatements should be lowercase; see Rule 29.
Manage variables using MODULECollect variables into
MODULE Sharedwith modern declaration syntax; if possible, include
PARAMETERconstants to 15 decimal places (double precision) and employ derived-type objects using
USE only what you needImport as many module entities as is practical into procedures with
USE Shared, ONLY :. The statement
IMPLICIT NONEalways follows a
Double precision everywhere
USE, INTRINSIC :: ISO_Fortran_env, dp=>REAL64. Also, use the suffix
_dpas a way of casting a single precision literal using a
1.234_dp. It can be nicer to look at in some cases (see more here).
Text labels on DO loopsGive your
DOloop a name:
my_loop: DO ... END DO my_loop.
Use ALLOCATABLE arrays
ALLOCATABLEarrays offer significant advantages in memory management and execution speed when the functionality of pointers is not needed.
Use uppercase exponent notation
E−. Of course, one could go a step further and replace all
Ds—see Rule 8. Make sure to pad single-digit exponents, e.g.,
Release files from their associated UNIT numbersAlways pair a
CLOSEstatement with an
.datextension on file names.
Don't have bare END statements'Tis better for all
ENDstatements to specify what they are ending, e.g.,
END MODULE Shared.
PROGRAM name and file name should be the same
Use a consistent set of rules for case
Use optional white space in statements and keywordsTake advantage of separating blanks in (and around) statements and keywords. Things like
Place a space after all commasAlso: use single quotes,
', for internal strings and double quotes,
", for external strings.
Use symbolic relational operatorsMake your code more closely resemble the mathematics by adopting the symbolic relational operators
Use square bracket notation for array constructorsFor rank 1 arrays, Fortran 2003 introduces the use of square brackets
to delimit an array constructor. For arrays of rank 2 or greater, the
DATAstatement needs to be used … usually declared in a module.
Indicate the intent of all dummy argumentsIn subroutines, aid the compiler in discovering errors in your program by providing an
Reduce long argument listsPass derived-type objects between procedures. (These don't need to be passed as dummy arguments.) Especially handy if a group of parameters has an identifiable theme.
Use assumed-shape arrays as dummy array arguments in subprogramsFor example,
REAL, INTENT(IN OUT) :: dummy_array(:); see Rule 25. The compiler may request that you write an explicit interface for your subprogram:
Explicit interface required for ... assumed-shape argument. In doing so, you will be assisting the compiler in looking for potential problems. See the Notes for more details.
Allow strings of varying lengthDeclare an assumed-length string:
CHARACTER(LEN=*), INTENT(IN) :: string; use a deferred-length parameter specification:
CHARACTER(LEN=:), INTENT(IN OUT), ALLOCATABLE :: dummy_string. Rule 29. has more info on usage.
Write all loops that index arrays of rank 2 or greater (nested loops) such that the innermost rank varies firstTo avoid large jumps in memory references, arrange loops to vary indices in "reverse" order.
Assign the CONTIGUOUS attribute to assumed-shape arraysAssist the complier in generating optimized code by avoiding unnecessary copying of data when invoking subprograms.
Manage UNIT numbers as a resourceGive your file a name:
INTEGER, PARAMETER :: my_file = 10; avoid using single-digit unit numbers. Remember that Fortran reserves two unit numbers for user I/O with respect to the
5for input (read) from the keyboard and
6for output (write) to the screen. Also, consider replacing
PRINT *statements with formatted
WRITE(6, '(...)', advance='no')output statements if you happen to be reading input from the user.
Use recommended specifiers in OPEN statementsEspecially recommended are the specifiers
action. See Rule 28.
Use ASYNCHRONOUS I/O in OPEN statementsDeclare:
REAL, DIMENSION(:), ALLOCATABLE, ASYNCHRONOUS :: my_array; implement:
Use named character constants for format specificationsGive your format a name:
CHARACTER(*), PARAMETER :: my_format = '(a, i0, a, g14.7, a)'.
Make dummy arguments predictable and informativeAppend the characters
sto dummy arguments to specify a
SUBROUTINE, respectively. This has the benefit of informing the programmer how many "levels deep" these parameters are within the overall context of your program. For example,
my_variablefsfis buried function-subroutine-function "below" the main program.
ReferencesMetcalf, Michael. Modern Fortran Explained. Oxford: Oxford University Press, 2011.
Clerman, Norman. Modern Fortran: Style and Usage. New York: Cambridge University Press, 2012.
"What does "Error: Explicit interface required for '*' at (1): assumed-shape argument" mean?" Computer Groups.