Style Rules
integer :: i,j,k ! Spatial indices
Continuation lines are acceptable on multi-dimensional array declarations which take up many columns. For example:
real(r8), dimension(plond,plev), intent(in) :: &
array1, &! array1 is blah blah blah
array2 ! array2 is blah blah blah
Note that the f90 standard defines a limit of 39 continuation lines.
a = b + c*d + blahblahblah/xxxxxxxxxx + &
h*g + e*f
call sub76 (x, y, z, w, a, &
b, c, d, e)subroutine sub76 (x, y, z, w, a, &
b, c, d, e)
call linemsbc (u3(i1,1,1,j,n3m1), v3(i1,1,1,j,n3m1), t3(i1,1,1,j,n3m1), &
q3(i1,1,1,j,n3m1), qfcst(i1,1,m,j), xxx)
subroutine linemsbc (u, v, t, &
q, qfcst, xxx)
!
! Describe what is going on
!
Key features of this style are 1) it starts with a "!" in column 1; 2) The text starts in column 3; and 3) the text is offset above and below by a blank comment line. The blank comments could just as well be completely blank lines (i.e. no "!") if the developer prefers.
The second condition in which it is desirable to put multiple routines in a single file is when they are "CONTAIN"ed in a module for the purpose of providing an implicit interface block. This type of construct is strongly encouraged, as it allows the compiler to perform argument consistency checking across routine boundaries. An example is:
file 1:
subroutine driver
use mod1
real :: x, y
...
call sub1(x,y)
call sub2(y)
return
end subroutine
file 2:
module mod1
private
real :: var, var2
public sub1, sub2contains
subroutine sub1(a,b)
...
return
end subroutinesubroutine sub2(a)
...
return
end subroutineend module
The number, type, and dimensionality of the arguments passed to sub1 and sub2 are automatically checked by the compiler.
The final reason to store multiple routines and their data in a single module is that the scope of the data defined in the module can be limited to only the routines which are also in the module. This is accomplished with the "private" clause.
If none of the above conditions hold, it is not acceptable to simply glue together a bunch of functions or subroutines in a single file.
!-----------------------------------------------------------------------
!
! Purpose:
! <Say what the routine does>
!
! Method:
! <Describe the algorithm(s) used in the routine.>
! <Also include any applicable external references.>
!
! Author: <Who is primarily responsible for the code>
!
!-----------------------------------------------------------------------
Inclusion of the "Method" portion is not required when not applicable, such as a module which contains data but no subroutines. Note also that the "Author" portion is expected to be filled in by hand, *not* automatically by the cvs variable "$Author".
Package Coding Rulessubroutine sub1 (x, y, z)
implicit none
real(r8), intent(in) :: x
real(r8), intent(out) :: y
real(r8), intent(inout) :: zy = x
z = z + xreturn
end
The term "package" in the following rules refers to a routine or group of routines which takes a well-defined set of input and produces a well-defined set of output. A package can be large, such as a dynamics package, which computes large scale advection for a single timestep. Or it could be relatively small, such as a parameterization to compute the effects of gravity wave drag.
subroutine sub
logical first/.true./
if (first) then
first = .false.
<set time-invariant values>
end if
integer, parameter :: r8 = selected_real_kind(12)
integer, parameter :: i8 = selected_int_kind(13)
Thus, any variable declared real(r8) will be of sufficient size to maintain 12 decimal digits in their mantissa. Likewise, integer variables declared integer(i8) will be able to represent an integer of at least 13 decimal digits. Note that the names r8 and i8 defined above are meant to reflect the size in bytes of variables which are subsequently defined with that "kind" value.
real(r8) :: arr(1)
where "arr" is an input argument into which the user wishes to index beyond 1. Use of the (*) construct in array dimensioning to circumvent this problem is forbidden because it effectively disables array bounds checking.
The preferable mechanism for dynamic memory allocation is automatic arrays, as opposed to ALLOCATABLE or POINTER arrays for which memory must be explicitly allocated and deallocated. An example of an automatic array is:
subroutine sub(n)
real :: a(n)
...
return
end
The same routine using an allocatable array would look like:
subroutine sub(n)
real, allocatable :: a(:)
allocate(a(n))
...
deallocate(a)
return
end