Fortran/Fortran overview

Part of the Fortran WikiBook

This section is a quick reference on changing from other languages to Fortran.

Common Mistakes
Listed below are some common mistakes made when using Fortran by users of C or Java:
 * Perhaps the most common mistake when moving from one language to another is to try to make the new language look or act too much like the previous language in use. When switching to Fortran (for whatever reason) consider doing things the Fortran way, rather than as you would in some other language.
 * In Fortran, variables need not be declared. A new variable beginning with  through   (the "in" group) is an  . A variable beginning with some other letter is a  . So, the disadvantage is that a typo could result in a new variable. The advantage is that coding is fast and easy, in that for most cases, no variables need be declared. If you want Fortran to act like declaration required languages, use   at the top of each program, function, and subroutine.
 * Arrays are indexed from 1 to N, not 0 to N−1.
 * Arguments passed to functions and subroutines are passed by reference and not by value. Additionally, languages like C typically push each of their arguments onto the stack. Many (if not most) Fortran implementations build an array of argument addresses, and push the address of that array (only) onto the stack. This uses slightly more storage, but less executed code if you average more than 1 argument. The C-user error occurs when you think you know the addresses of argument references.
 * Note that arguments may need to be declared, and might not, as per the rules above.
 * For fixed form code, the first 6 columns have special meanings, and you can only use the first 72 columns.
 * Trying to use allocation too much. When in Fortran, try to use static allocation of arrays whenever possible.
 * Thinking you know how big a variable is—Here are the rules:  can be any number of bytes.   is at least as big as  .   is at least as big as  .   is at least as big as  . And finally,   is twice as big as  . Typically, the sizes are 1, 4, 4, 8, and 8 bytes, respectively, but don't rely on that if you're writing portable code. A related mistake is thinking that   or   gives you data 4 or 8 bytes wide. The number following the   is a suggestion, not a requirement.

Variables
C / C++ int i; double x[3]; double *y = NULL; y = new double[3]; delete[] y; { 1, 2, 3}; // <- Do the semantics match exactly? Fortran (with two examples of allocation and deallocation—don't use both at once) INTEGER i DOUBLE PRECISION x(3) DOUBLE PRECISION, DIMENSION, ALLOCATABLE :: xx DOUBLE PRECISION, POINTER, DIMENSION :: y => null ALLOCATE(xx(3)) DEALLOCATE(xx) ALLOCATE(y(3))                   ''! memory allocation for pointer - similar syntax to array allocation'' DEALLOCATE(y)                    ''! again similar syntax as for array allocation / deallocation'' (/ 1, 2, 3 /)

Caveat: Fortran's arrays are more flexible than plain C arrays. By default they are indexed from 1 not 0.

They may be declared to be indexed by different means:

REAL, DIMENSION(-2:10) :: A

means you can use A(10) as well as A(-2).

Multidimensional arrays should be declared this way:

REAL A(5,7,10)

You will have 5*7*10 elements from A(1,1,1) to A(5,7,10). Note memory is laid out in a way unique to Fortran. The element in memory following A(1,1,1) is A(2,1,1), and not A(1,1,2).

You can use parts of array this way:

REAL A(10,10) REAL B(3,3)

B(1:3,2:3)=A(4:6,7:8)

will act as

DO i=1,3 DO j=2,3 B(i,j)=A(i+3,j+5) END DO END DO

Which is the same as the archaic but shorter form

DO 1 i=1,3 DO 1 j=2,3 1 B(i,j)=A(i+3,j+5)

Functions & Subroutines
In Fortran, s return a value whereas  s do not. In C/C++ this is simply the distinction between returning a value or returning. In Fortran, the name of the function is assigned to return a value from a function. When calling, a subroutine is called with the  keyword whereas a function is called as in C/C++. When there are no arguments, an empty parenthesis is not needed.

C/C++: int foo(int i, int j) { ...  return 42; } // then later: int x = foo(1, 2); Fortran: INTEGER FUNCTION foo(i, j) ... foo = 42 END C then later: k = foo(1, 2) C/C++: void bar(double j) { ... } void baz { ...  return; // Can return in the middle. ...  return; // Optional for a function returning void. } // then later: bar(42.0); baz; Fortran: SUBROUTINE bar(x) ... RETURN ... END SUBROUTINE baz ... END C then later: CALL bar(42.0) CALL baz

if &rarr; if, then, else, end if
C / C++ if (...) { ... } else if ( ... ) { ... } else { ... } Fortran if (...) then ... else if (...) then ... else ... end if

switch &rarr; select case, case, end select
C/C++ switch (...) { case ...: ...;  break; // Without "break", control "falls through" to the next case. default: // The "default" case is optional but advisable. ...;  break; // Not necessary for the last case. } Fortran select case(...) case (...) ...   case default ... end select

for &rarr; do, end do
C/C++ for (i = 1; i <= 10; i++) { ... } Fortran do i=1,10 ... end do