F90 Reference Manual
F90 Reference Manual
Concise Reference
Jerrold L. Wagener
All rights reserved. No part of this book may be reproduced in any form or by any
electronic or mechanical means (including photocopying, recording, or information
storage and retrieval) without written permission from the publisher.
This book was set by the author and published, in both printed and electronic form,
in the United States of America by Absoft Corporation.
ISBN
Contents
Contents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . i
Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . v
1 Program Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
program units . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
4 Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
array-valued expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
conformability and element-by-element computation . . . . . . 26
array constants - array constructors . . . . . . . . . . . . . . . . . . . . 27
masked array assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
assumed-shape dummy arguments . . . . . . . . . . . . . . . . . . . . 30
array elements and sections . . . . . . . . . . . . . . . . . . . . . . . . . . 30
dynamic arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
array-valued functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
example - picture refinement . . . . . . . . . . . . . . . . . . . . . . . . . 36
example - Gaussian elimination . . . . . . . . . . . . . . . . . . . . . . . 37
5 Redundancy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
common blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
equivalence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
attribute statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
block data program unit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
deprecated features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
6 Input/Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
inputting data (read) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
outputting data (write) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
data formats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
opening and closing files . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
file inquiry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
sequential and random files . . . . . . . . . . . . . . . . . . . . . . . . . . 56
partial-record (nonadvancing) I/O . . . . . . . . . . . . . . . . . . . . . 57
list-directed and name-directed I/O . . . . . . . . . . . . . . . . . . . . 60
7 Control Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
if construct . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
case construct . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
do construct . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
goto statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Table of Contents iii
8 Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
module structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
module use . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
module applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
9 Procedures 75
subroutines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
host association . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
procedure arguments and argument association . . . . . . . . . . 79
interface blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
generic procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
return statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
statement functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
entry statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
intrinsic procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
10 Intrinsic Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
Preface v
Preface
Fortran has been the principal programming language of the scientific community since
the mid-1950s and has evolved over that time. The 1978 standard version, called Fortran
77, saw extremely wide use. Fortran 90 is the next step in the evolution of Fortran; it sup-
ports all of the features of Fortran 77 as well as many new ones which can make program-
ming easier and more efficient. The purpose of this book is to provide a concise yet
complete reference for Fortran 90.
Though there are numerous examples, this reference is neither a programming nor Fortran
90 tutorial; it assumes some familiarity with Fortran 77 programming. Though focusing
mainly on standard Fortran 90, a separate chapter on the Absoft implementation of Fortran
90 describes implementation-specific features, including extensions to support interopera-
bility with other languages and to facilitate porting of extended Fortran 77 legacy code.
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
Chapter 1 summarizes various “structural” aspects of a Fortran 90 program: source form,
program units (e.g., procedures, modules) “parts” (e.g., specification part, execution part),
etc. It also indicates how to read the formal syntax rules (BNF), heavily relied upon
throughout.
Chapter 2 describes the Fortran 90 intrinsic data types. Those familiar with Fortran 77 will
recognize them all. The one new feature here is the type “kinds” and kind parameters. All
implementations must provide at least two kinds of reals (single and double precision),
and may provide more; accordingly the Fortran 77 double precision type is deprecated.
Chapter 3 describes the Fortran 90 features for user-defined data types, formally called
derived types (as they are derived from the intrinsic types). This provides for the first time
in standard Fortran, data structures, including dynamic (linked) structures, and most of the
data abstraction capabilities of a modern object-oriented language. The generic procedure
and data abstraction features are superb (but lacking are inheritance and polymorphism).
Chapter 4 describes the Fortran 90 array-processing language. This is one of the major
features of Fortran 90, and gives the language much of the array power (albeit with Fortran
syntax and efficiency) of APL. In addition to array-level operations, there are two new
facilities for dynamic arrays, including a couple of flavors of allocatable arrays.
Chapter 5 is an identification of many of the Fortran 90 features that are redundant with
other (usually more modern) features. This includes the features “deprecated” in the For-
tran 90 standard and which may therefore be removed in future versions of the Fortran
standard.
Chapter 6 describes the Fortran 90 Input/Output facilities. There's not much new here
beyond Fortran 77, additional file connection specifiers and name-directed (namelist) I/O
being the main ones. These features require two chapters and 47 (large) pages to fully
describe in the Fortran standard; they consume 127 (smaller) pages in the exhaustive For-
tran 90 Handbook (see below).
vi Fortran 90 Concise Reference
Chapter 7 describes the Fortran 90 control structures. To the Fortran 77 if construct are
added: a case construct and three modern loop constructs (do while, do forever with exit, a
modern form of the indexed do).
Chapter 8 describes the Fortran 90 module program unit and its uses. This is a major addi-
tion to Fortran and provides flexible software “packaging”, complete with information
hiding (public, private) capabilities.
Chapter 9 describes the Fortran 90 procedure facilities. Much of this will be familiar to
Fortran programmers, but there are some significant features new in Fortran 90. These
include explicit procedure interfaces, user-defined generic procedures, module and inter-
nal procedures, and operator definition.
Chapter 10 summarizes Fortran 90's 113 intrinsic procedures. These include, in addition to
the traditional numeric and character computational functions, numeric environmental
inquiry functions, array-processing and inquiry functions, bit-processing procedures, and
a few intrinsic subroutines.
Chapter 11 is the complete BNF for Fortran 90, extracted from the Fortran standard. This
is the rigorous description of the Fortran syntax, and this reference relies very heavily on
it; in many cases reference to the syntax rules in chapter 11 is the extent to which the syn-
tax is described, with the text devoted primarily to describing the semantics and con-
straints related to the syntax.
Chapter 12 describes various implementation-specific values (e.g., kind values), options
(e.g., compiler options), and extensions in the Absoft implementation of Fortran 90.
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
This reference is intended to completely describe all of Fortran 90, but being concise it
may give short shrift to some of the more subtle details of the language. The recom-
mended sources to pursue these details are the following:
1. The Fortran standard. A committee draft of the version of the Fortran standard cur-
rently under development is available on the Fortran standard committee’s web site,
http://www.ionet.net/~jwagener/j3. As of this writing standing document J3/007 is the
working draft of the Fortran 2000 standard, a very substantial subset of which is the
official definition of Fortran 90 (less five of the deprecated Fortran 90 features);
because of copyright restrictions the Fortran 90 standard cannot be posted publically.
2. The Fortran 90 Handbook, by Adams, Brainerd, Martin, Smith, and Wagener. This
book was published by McGraw-Hill in 1992, and is an exhaustive, 740-page refer-
ence on Fortran 90; its chapter organization is the same as the Fortran 90 standard and
it was intended as a “readable version” of that standard.
Jerry Wagener
June 1998
[email protected]
Program Structure 1
1 Program Structure
This concise reference to Fortran 90 summarizes all aspects of the language in a crisp,
concise manner. This reference is neither a programming nor Fortran 90 tutorial; it
assumes some (but not extensive) familiarity with Fortran 77 programming concepts.
This chapter summarizes various "structural" aspects of a Fortran 90 program: source
form, program units (e.g., procedures, modules), "parts" (e.g., specification part, execution
part), etc. It also indicates how to read the formal syntax rules (BNF) used throughout.
syntax
Chapters 1-9 rely heavily on, and make frequent reference to, chapter 11, which is a com-
plete BNF description of Fortran 90; while there are numerous examples of syntax
throughout, this reference primarily lets syntax rules (each with an “R” number) of chapter
11 "do the talking" for a complete and rigorous account of the Fortran 90 syntax. The var-
ious chapters describe the associated semantics; no semantics are omitted, though some
(especially those related to the "deprecated" features) are indeed brief.
The characteristics of the formal BNF of chapter 11 are summarized at the beginning of
that chapter. A somewhat more informal form often will be used in chapters 1-9 in describ-
ing a feature. For example: a Fortran 90 programmer-defined name is (R304):
letter [ name-character ] ...
where a name-character is a letter, (decimal) digit, or underscore(_) character.
The maximum length of a name is 31 characters; letters may be either upper or
lower case (the case is not significant in names and keywords).
Square brackets ([ ]) indicate optionality and square brackets followed by three dots ([ ] ...)
indicate optionally repeated any number of times. Constraints (like the 31 limit for name
lengths) will be mentioned. In those cases where the language imposes no constraints, an
implementation might. To take an extreme example, the internal subprogram part of a
function (say) may contain, according to the BNF, [ internal-subprogram ] ... without limit;
clearly no contemporary implementation could cope with a function having ten trillion
internal functions, even if the programmer could (!?).
Chapters 1-9 will contain a number of short, illustrative examples. The predominant style
in these examples will be: keywords in all lower case (if, end), procedure and variable
names starting with a lower-case letter (x, midPoint), main program, module, and derived-
type names starting with an upper-case letter (HelloWorld, RangeArithmetic), constants in
all upper case (N, QUAD), "free-form" source (described below), and modest indentation of
internal structure. A (nonsense) example is:
program HelloWorld ! nonsense example
use RangeArithmetic ! this program uses a module
real(QUAD) :: X(N) ! a "quad-precision" array
type(Range) :: m1=Range(0,6) ! variable of user-defined type
x(1) = midPoint(m1)
2 Fortran 90 Concise Reference
There are no column restrictions in free-form source, except that lines have a 132 charac-
ter limit, and an exclamation point (!) initiates an end-of-line comment (from where it
begins to the end of that line). Blanks must be used to separate keywords and names (e.g.,
the blanks are significant in program HelloWorld and use RangeArithmetic above); the other
blanks in the above example are used for purposes of readability, not because they are syn-
tactically required by the language)1. The above program is syntactically legal Fortran 90
if (and only if) a module named RangeArithmetic exists and it defines integer constants N
and QUAD, a derived-type named Range, and a real (or integer) function named midPoint
that takes an argument of type Range.
Every Fortran program is a set of program units, each of which is a sequence of statements
- the above example has nine statements, each on a separate line. This is the normal pat-
tern, but there are two other aspects of free-form source, both used occasionally, but spar-
ingly, in subsequent examples: (1) two (or more) statements can appear on the same line,
separated by a semicolon (the second statement can be null if you want to simulate the C
style of ending a statement with a semicolon); (2) a statement can be continued on the next
line by ending the (first) line (before any end-of-line comment) with an ampersand (&).
program units
A Fortran program is a set of (related) individual program units (R201), consisting of one
main program (R1101), zero or more external subprograms (R203), zero or more modules
(R1104), and zero or more block data units (R1110). The Fortran standard does not spec-
ify "where" these parts reside on a computing system, but typically one or more complete
units are placed in a file; each such file is a separately-compiled compilation unit. The
order of compiling such compilation units is normally immaterial, except that a module
must be compiled before any units using that module, and the main program should be
compiled last if an executable program is to be prepared therefrom. (For small programs
everything can be placed in one file, with the modules first and the main program last.)
1. In Fortran’s original fixed-form source (see chapter 5) blanks are never significant (e.g.,
never required) except in character strings, but blanks could be used freely for improv-
ing readability. Blanks could even be used within keywords and names; for example:
integer could be written int eger. In free-form source blanks are significant (token
delimiters) and must not be used within a keyword, name, or constant (except character
constants), and (one or more) must be used to separate (delimit) consecutive keywords
and names. The exceptions to this rule are that the separating blanks are optional in the
following keyword sequences: block data, double precision, else if, go to, in out, select case,
and all that start with the word end. The nonletter nondigit characters serve as delimiters
and blanks may be freely used with (on either side of) them.
Program Structure 3
A large program unit can be spread across multiple files and “put back together” with
include lines in a compilation unit. The include line, which is not a Fortran statement (but
rather a compiler directive), has the form include file-name and cannot have an end-of-line
comment; during compilation the compiler replaces the include line with the contents
(e.g., common block definitions) of the specified file. With the advent of modules in For-
tran, there are not many situations in which the include line is needed.
Execution of a program begins with its main program, which may call procedures defined
in external subprogram units and modules to perform computations. In addition, modules
may provide the main program (or any of the procedures it calls) with various “global”
entities, such as global constants and variables, type definitions, and procedure interfaces.
Ignoring the (unnecessary and not recommended) “attribute” statements (R519-538) - see
chapter 5 - the eight sections of these program units are as depicted in the following dia-
grams.
Sections 1 and 8 define the beginning and end of the program unit, and are the only sec-
tions that are not optional. Section 2 provides the program unit access to any modules it
uses. Section 3 modifies the implicit environment (or replaces it with implicit none). Sec-
tion 4 is the heart of the specification part of the program unit; it is here that all the local
constants and variables are declared and any derived types and interface blocks not pro-
4 Fortran 90 Concise Reference
vided by modules are defined. Section 5 is the execution part, which represents the pri-
mary computation part of the program unit; note that modules do not have an execution
part (they are intended as a source of definitions used by other program units). Section 6 is
a keyword that marks the beginning of any internal or module subprograms (section 7);
sections 6 and 7 go together - if one is present the other must be also. Each internal or
module subprogram has the same structure as an external subprogram, except that internal
subprograms cannot themselves contain internal subprograms. Note that a module may
access other modules (and pass their definitions on to other program units using that mod-
ule).
statements
A Fortran statement is made up of keywords, names, expressions, and delimiters. Key-
words are predefined words that have some special meaning; most statements start with a
keyword (e.g., print, end, integer, function, etc.). Names are programmer-defined, as
described above, and are used to give unique identifiers to variables, constants, proce-
dures, modules, etc. Expressions are the “computational engines” that generate computed
results; they are formed from operands and operators. Operands include constants, vari-
ables, and function calls, and are described in the next chapter and in other appropriate
places throughout; operators are either special characters (+, -, *, **, /, //, ==, /=, <, <=, >, >=)
or letters enclosed in periods (.eq., .ne., .lt., .le., .gt., .ge., .and., .or., .eqv., .neqv., .not., and
user-defined operators, R311).
Delimiters include blanks (as described above), = (for assignment - see below), % (struc-
ture component selector, R612 and chapter 3), left and right parentheses (multiple “enclos-
ing” uses), single and double quotes (character constant delimiters - see chapter 2), the
comma (list separator), : and :: (other separators), ! (comment initiator), & (statement con-
tinuation), and the semicolon (statement separation).
The only statements that do not begin with a keyword are the assignment statement (R735)
and the statement function (R1226), which have similar forms; the statement function is
described in chapter 9. The assignment statement has the form
variable = expression
and has the purpose of saving the value of a computation (expression) so that the value can
be used in subsequent computations. The variable (R601-602) is where the value of the
expression (R723) is saved (the previous value of the variable is replaced); the variable may
be a scalar variable name, an array variable name (for results of an array expression - see
chapter 4), an array element, an array section (see chapter 4), a structure component (see
chapter 3), or a substring (see chapter 2). Normally the type and kind of the variable must
be the same as the type and kind of the expression value, but this rule is relaxed when
numeric values are involved (see chapter 2). The expression can represent an arbitrarily
complex computation involving operators and operands; the main features of expressions
are described in chapter 2, with expressions involving user-defined types in chapter 3 and
whole arrays (and array sections) in chapter 4.
Intrinsic Data Types 5
Fortran 90 has “built-in” (intrinsic) data types and user-defined (derived) data types; the
latter are described in the next chapter. The intrinsic data types may be categorized as the
numeric types (integer, real, and complex) and the nonnumeric types (character and logi-
cal). Each of these may have any number of kinds, though an implementation need provide
only one kind of integer, character, and logical, and two kinds (“single” and “double” pre-
cision) of real and complex. Typical additional kinds that an implementation may provide
are long and short integers, “quad” precision for real and complex, additional national
character sets (the default character kind is essentially ASCII), and one-bit (or one-byte)
logically. Arrays of any of these intrinsic type/kinds are permitted, with full array opera-
tions appropriate for that type.
The kinds are specified by integer constants called kind type parameters, and allow types
to be “parameterized”. Thus a given program can, for example, be run with some set (or
all) of the real variables having single precision; on another run these variables could be
double precision. Across procedure boundaries both the type and type kind parameters of
associated actual and dummy arguments must match, and thus kind mechanism can be
used to provide families of generic procedures in procedure libraries. Each type has a
“default” kind that is used for variables for which a kind type parameter is not explicitly
declared; for example, the default real (and complex) kind is “single precision” and the
default character kind is (essentially) ASCII.
135843_LONG
-687
The second of these examples illustrates how the kind parameter is specified for constants
(“attached” to the value by the underscore); in this case LONG is a named integer constant
having a valid kind value provided by the implementation. (See the intrinsic functions
kind, and selected-int-kind to determine the implementation’s kind values for integers and
see the intrinsic functions range, huge, and tiny to determine the range for any integer
kind.)
6 Fortran 90 Concise Reference
The usual operations are provided intrinsically for two integer operands: addition (+), sub-
traction (-), multiplication (*), division (/), and exponentiation (**). Such operations all pro-
duce (the usual) integer results, the only potentially surprising one being integer division,
which results in the truncated arithmetical result. Plus (+) and minus (-) may also be used
as unary operators with integer operands with the usual results. The other intrinsic opera-
tions on integers are the relational operators ==, /=, <, <=, >, >= (or, equivalently, .eq., .ne.,
.lt., .le., .gt., .ge.) for comparing two integer values. Respectively, these operations result
in the logical value .true. if the first integer operand value is equal to, not equal to, less
than, less than or equal to, greater than, or greater than or equal to the second integer oper-
and value, and .false. otherwise. Examples of operations involving integer operands are:
j+k
j-k*n ! evaluated as j - (k * n)
(j - k) * n
j-k+n ! evaluated as (j - k) + n
-(j + k)
(-j) * k
j/k*n ! evaluated as (j / k) * n
j / (k * n)
k ** n
j<k
Note that parentheses may be used in the usual way to specify evaluation order in expres-
sions containing multiple operations. The usual default precedence (e.g., left-to-right and
multiplication-before-addition) is used in the absence of parentheses, and the numeric
operations take precedence over the relational operations. See R723 for a rigorous descrip-
tion of the precise rules for evaluation of expressions involving integer operands. Addi-
tional (user-defined) operations may be provided for integers - see chapter 9.
Though (arguably) Fortran does not provide an intrinsic bit data type (but see the logical
type) a complete bit processing facility is provided via integer objects and intrinsic proce-
dures btest, iand, ibclr, ibits, ibset, ieor, ior, ishft, icshft, mvbits, and not. These provide bit-
by-bit operations on non-negative scalar integer values represented by binary digits (bits)
according to the model v = ∑bi2i, 0≤i<m. Integer constants may, alternatively, be speci-
fied or printed as a set of binary digits, octal digits, or hexadecimal digits, in accordance
with R407, and R1005. The rightmost bit in the integer object is b0 and, for example, the
integer value 13 (or B"1101" or O"15" or Z"D") represents the bit string . . . 0001101.
Intrinsic Data Types 7
4.3
-22.9E22_QUAD
.123
123.
The fourth of these examples illustrates the use of a kind parameter in a real constant -
QUAD is a named integer constant having a valid kind value provided by the implementa-
tion for reals. As mentioned above, an implementation must provide at least two kinds of
real, informally known as single and double precision. (See the intrinsic functions kind
and selected-real-kind to determine the implementation’s kind values for reals.) Note that,
unlike for integers, a real constant may not be representable exactly; for example the real
constant 0.1, though within range for (most) real types, is not representable exactly in a
binary implementation (that is, one for which r=2 - e.g., the IEEE floating point standard).
Exactly the same intrinsic operations as for integers are provided for real operands, with
the same meanings, except that division works “normally”. Because of the potential noted
above for inexact representation of real values, the equality relational operators (== and /=)
may at times yield “unreliable” results and thus should be used with care (if at all) with
real operands. As for integers, see R723 for a detailed descriptions of the syntax and
semantics (precedence) of expressions involving intrinsic operators with real operands,
and see chapter 9 for expressions involving user-defined expressions with real operands.
8 Fortran 90 Concise Reference
The last two examples above are double precision constants; using the D (instead of E or
neither) makes the constant the double precision kind of real rather than the (default) sin-
gle precision kind. The data type double precision (R502), before the advent of the kind
concept in Fortran, was the only way that double precision objects could be declared. The
double precision type is still available, but is now deprecated in favor of real(kind(1D0));
double precision and real(kind(1D0)) represent identical type/kind combinations.
( 5, 5.5E5 )
( -3.3_QUAD, 4.4_QUAD )
The complex type has the same intrinsic numeric operators (+, -, *, /, **) as the other
numeric types, with the usual meanings. However, since complex values do not have a nat-
ural ordering, the equality operators (== and /=) are the only intrinsically defined relational
operators for complex. Because comparison of complex values involves comparison of
real values, the same comparison caveat applies to complex values as to real values.
Though intrinsic meanings for <, >, etc., are not provided for complex, an application may
provide such meanings as user-defined operators - see chapter 9.
Intrinsic functions real and aimag return the real and imaginary parts, respectively, of a
complex argument. Function conjg returns the complex conjugate of a complex argument,
and function cmplx allows construction of a complex value of any kind from any integer or
real values (e.g., any integer or real expressions, not just constants) and conversion of
complex values to different complex kinds. Intrinsic function int converts any integer, real
or complex argument to any kind of integer value, and function real converts any integer,
real or complex argument to any kind of real value.
values than is required for default logical values. One bit is adequate for representing a
true/false (1/0) value, though one byte (8 bits) is often used as well. A logical kind in
which exactly one bit is used to represent a logical value has many of the properties of a
bit data type (especially in the form of logical operations on logical arrays).
There are four intrinsic binary operators that take logical operands (.and., .or., .eqv., .neqv.)
and one unary operator (.not.). The results of these operations are shown in the following
table, where T stands for .true. and F stands for .false.
y=T T F T T T F F T F
y=F F F T F F T T F T
x .and. y x .or. y x .eqv. y x .neqv. y .not.y
Note that relational operations on numeric values result in logical values, which can then
be used as operands in logical operations; for example: x < y .and. y < z (meaning x<y<z).
'x'
GREEK_"µøπß"
There is just one intrinsic character operator, the concatenation operator (//); it appends the
second operand to the first, forming a longer character string:
"blue" // "whale" ! results in "bluewhale"
10 Fortran 90 Concise Reference
There are a number of intrinsic procedures that are very useful for a wide range of charac-
ter processing, including the following functions: len, index, trim, adjustl, scan, etc. Two
such functions, char and ichar, provide conversion between characters and integers. The
characters have a collating sequence, which is a one-to-one mapping between the charac-
ters and (a subset of) the integers. Function char takes an integer argument and returns the
character associated with that integer value in the collating sequence; function ichar does
the reverse, returning the collating-sequence integer associated with the character argu-
ment.
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
declarations
Making a specific variable name have a specific type is known as a data object declaration,
type declaration, or just declaration for short. Declarations are used as well to establish
named constants and to type function results. The simplest form of a type declaration
(R501) is:
type-spec [ :: ] object-list
where type-spec (R502) is, for intrinsic types, the type name (integer, real, complex, logi-
cal, character)
with an optional kind specification and, for character, an optional length
specification. Examples of declarations of simple, uninitialized scalar variables
are:
integer :: i, j
integer(SHORT) :: k
real :: ab, cd
real(QUAD) :: eps
real(DOUBLE) :: p, q2
complex :: z1, z2
complex(QUAD) :: tp3
logical :: done
character(10, GREEK) :: g, h5
The :: is optional, but it makes a nice visual barrier for the more complicated declarations
(to be described below) and so will be used consistently in examples henceforth. The kind
parameters (SHORT, QUAD, GREEK) are named integer constants; the actual integer values
could be used in place of the named constants, but since kind parameter values are not
standardized, and differ from implementation to implementation, the better practice is to
have the actual value appear only once - where the named constant is defined. If the kind
value DOUBLE has the appropriate integer value, the fifth example above is equivalent to
using (the deprecated) type name double precision (without a kind specification). The
Intrinsic Data Types 11
same declaration is obtained by using real(kind(1D0)) instead of real (DOUBLE), and indeed
the value of DOUBLE could have been specified, in its definition, as kind(1D0).
All of the objects in a character type declaration have the length specified in the type-spec,
unless overridden as illustrated by s3*30 in the next-to-last example above; s1 and s2 both
have length 20, while s3 has length 30. If the length specification is omitted, the value 1 is
assumed; if the length is omitted and the kind is not, then the kind= keyword must be used;
if both the length and kind are specified, with kind first, both the kind= and len= keywords
must be used; otherwise the kind= and len= keywords are optional (and the kind= keyword
is always optional in declarations of the other intrinsic types).
The above examples declared uninitialized scalar variables. The following examples illus-
trate how array objects can be declared and how objects (scalars or arrays) can be given
initial values.
integer :: i, j(10) ! j is an array of 10 elements
real(QUAD) :: eps=0.000001
complex(QUAD) :: tp3(1000,1000)
logical :: done=.false.
Arrays can have up to seven dimensions, the specification of which are enclosed in paren-
theses, and separated by commas; each has the form [ lower : ] upper, where lower and
upper are integer values which specify the lower and upper bounds of the subscript range
for that dimension; if the optional part is omitted, the lower bound is 1. Arrays are
described in detail in chapter 4, together with additional forms of array declaration (for
dynamic and dummy argument arrays).
An initial value is specified by an initialization expression, which can by any expression
(of an appropriate type) involving only constant values, with the following two exceptions:
(1) operators must be intrinsic operators and any exponentiation operator (**) must have a
second operand of type integer; (2) a procedure call must be to an intrinsic function that
(a) can be evaluated at compile type and (b) except for the reshape, transfer, and inquiry
functions, have arguments only of type integer and character and deliver a result only of
type integer or character. A variable local to a procedure may be initialized, but that initial-
ization is effective only at the first execution of the procedure and the variable, though
saved (see below) is not reinitialized at the beginning of subsequent executions.
12 Fortran 90 Concise Reference
attributes
The properties of data objects are called attributes; the most basic attribute, one that every
data object has, is type (and kind). The other attributes are optional and the two illustrated
above are the array (dimension) attribute and the initial value (data) attribute. There are 11
more attributes, the specification of which requires either the attribute form of the type
declaration statement (R501, R503) or a separate “attribute-oriented” statement for each
such attribute (R519-539). The attribute form of the type declaration statement is
type-spec , attribute-list :: object-list
The attribute-list can contain any of the attributes listed in R503, in any order, separated by
commas; but any given attribute can appear at most once in the list, and over half of them
are mutually exclusive (see the following table).
n
tio
ializa
initialization init
c
bli
public pu Shaded attribute combinations
ate are compatible; the others are
p riv
private al mutually exclusive.
tern
external ex ic
rins
int
intrinsic t
en
int l
intent ona
opti le
optional atab
alloc n
allocatable n sio
di me
dimension er
int
po
pointer t
ge
tar
target
ve
sa
save
parameter
Attributes public and private control the visibility of module objects and are described in
Chapter 8. Attributes external and intrinsic specify objects that are either external or intrin-
sic functions, respectively. Attributes intent and optional apply only to procedure dummy
arguments (see chapter 9). Attributes allocatable and dimension apply to arrays and are
discussed in chapter 4. Attributes pointer and target are used for dynamic structures,
including dynamic arrays, and are discussed in chapters 3 and 4.
Intrinsic Data Types 13
save
The save attribute is used to retain an object’s value when the object “goes out of scope”
and then comes back in. One example of this is local variables in a procedure; upon return
from the procedure, its local variables normally cease to exist, the space may be reallo-
cated for another purpose, and the variables are reinstantiated when the procedure is next
executed. However, any such variable with the save attribute remains intact with its value
unchanged between executions of the procedure, ready to “take up where it left off” when
the procedure is next executed. Initialized variables (and named constants) automatically
have the save attribute. A module variable goes “out of scope” and, without the save
attribute, becomes undefined whenever all program units using that module are inactive
(i.e., not executing). Similarly the save attribute is used to retain a common block and its
variable values when all program units using that common block are inactive.
parameter
A data object with the parameter attribute must also be initialized, and that value cannot be
changed - the object is a constant; it has a name and “looks” like a variable, and thus it is
called a named constant. Named constants are declared identically to initialized variables,
but with the parameter attribute. Named constants may be scalars or arrays, of any type,
and are extremely important to reliable programming. A constant that appears more than
once in a program, such as an array bound value or a kind parameter, should be a named
constant, and then when a change is needed in that value the change can be made in only
one place.
Examples of declarations with specified attributes are:
integer, parameter :: DOUBLE=kind(1D0)
numeric computations
As mentioned in chapter 1, computations are formulated as the results of expressions;
these results can then be assigned to variables, written (to the screen, the printer, or a file),
used as actual arguments in procedure calls, or used for control purposes (a logical expres-
sion as an if condition, ann array subscript, an integer expression as the final index value in
an indexed loop, etc.). In many respects, numerical expressions are the heart of Fortran
and, in addition to the four numerical types (counting both of the required real kinds) and
the numerical intrinsic operators, Fortran provides most of the elementary numerical func-
tions and the basic vector and matrix computations as intrinsic functions. In addition, the
facilities for providing user-defined computational libraries is very powerful.
Individual expression operands are defined in R701 and include constants (including
named constants), variables (scalars and array elements), function calls, and subexpres-
sions (expressions in parentheses). R723 defines expression structure in detail, including
operator precedence. Without the operator precedence, R723 boils down to this:
[ unary-operator ] numeric-operand [ binary-operator numeric-operand ] ...
The binary-operator precedence determines the execution order, but this can be controlled
with parentheses - that is, by making each operand a (parenthesized) subexpression, leav-
ing only one binary-operator at the top level; unparenthesized expressions are evaluated
as if the parentheses needed to represent the operator hierarchy had been added. For
numeric expressions the operators are power-op (R708), mult-op (R709), add-op (R710),
and unary and binary user-defined operators (R704, R724) delivering numeric results.
Note that R705-707 indicates that exponentiation, **, (power-op) has precedence higher
than any other numeric operator and works right-to-left for consecutive (unparenthesized)
power-ops (R705); multiplication and division (*, /), both mult-ops, have the same prece-
dence, which is higher than addition (+), and subtraction (-), both add-ops, and work left-
to-right (R706); additional and subtraction also work left-to-right (R707).
If a numeric operation has two operands with the same type and kind, it delivers a result of
that type and kind. Otherwise, the operation is “mixed-mode”, and one of the two oper-
ands (xw) will have a type/kind combination that is “wider” than that of the other operand
(xn); in this case the value of xn will be converted to the equivalent value in the xw number
system, the computation will be made at the xw type/kind level, and the result will have the
type and kind of xw; operand value conversion is performed as described below for mixed-
mode assignment. Any operand of type real is wider than any operand of type integer, and
any operand of type complex is wider than any operand of type real. Of two integer kinds,
the one having the greater integer range is the wider; normally this one will have the
greater kind value as well. Of two real (or complex) kinds, the one having the greatest pre-
cision is the wider; normally this one will have the greater kind value as well. By this rule,
double precision real/complex is wider than default (single precision) real/complex.
In numeric assignment, v=e, the variable v and the expression e can be any combination of
the numeric types (integer, real, complex). The value assigned is cf (e,kind(v)) where cf is
the intrinsic conversion function int, real, or cmplx, depending on whether v is type integer,
real, or complex, respectively.
Intrinsic Data Types 15
character computations
Character expressions (with intrinsic operators) are all of the form:
character-operand [ // character-operand ] ...
There are no intrinsic character unary operators, and concatenation (//) is the only intrinsic
character binary operator. Concatenation “works” left-to-right, but it doesn't matter since
concatenation is associative (A//(B//C) has the same result as (A//B)//C). The length of a con-
catenation result is sum of lengths of the two operands.
Character operands can be character constants, character variables (including character
array elements), functions delivering character results, character expressions in parenthe-
sis, and substrings (R609-611). The form of a substring is:
parent-string ( [ lower ] : [ upper ] )
where a parent-string can be a scalar character variable, a character array element, a char-
acter component of a structure, or a character constant; it cannot be a general character
expression, a character functional call, or substring itself. Lower and upper, which may be
arbitrary integer expressions, define the portion of the parent string that comprises the sub-
string; both lower and upper must have values greater than zero and less than or equal to
the length of the parent string. The length of the substring is upper-lower+1 (actually,
max(0,upper-lower+1)) and comprises the characters from index lower in the parent string
up to and including index upper. If lower==upper, then the substring is just one character -
that at index lower (or upper); if upper is less than lower then the substring is empty (has
length zero). Examples of substrings are:
s2(2:5)
lastName(k:)
address(i-1:index(address,'-'))
account % name(i:j)
The result of a character expression may, among other uses, be assigned to a character
variable (including an array element) of the same kind or to a substring of such a variable.
In either event the expression has a length (number of characters it produces) and the
receiving variable has a length (number of characters it receives). If these lengths are the
same, then the expression result becomes the value of the receiving variable. If the expres-
sion length is less than the receiving length, the expression result is padded on the right
with the requisite number of blank characters so that the two lengths are the same and then
the assignment is made; if the expression length is greater than the receiving length, the
expression is truncated on the right to the receiving length, and then the assignment is
made. Examples of character assignment are:
s1 = s1(1:4) // s2(5:) ! concatenate two substrings, then assign
implicit declaration
Unless implicit none is specified at the beginning of the program-unit (R205, R540), it is
possible to use variables in the program that have not been explicitly typed in type declara-
tion statements. Such variables will have the types specified by the implicit type environ-
ment in effect and are said to be implicitly typed. Such variables may be given other
attributes with “attribute-oriented” statements (R519-539).
The implicit type environment associates a type/kind combination to each letter. A name
not explicitly typed is implicitly typed according to its first letter. The default implicit type
environment is that letter I-N are associated with type default integer and all others are
associated with type default real. implicit statements (R540-542) may be used to change
these associations for some or all of the letters, and this may include implicitly typing for
the nondefault kinds and for user-defined types. implicit none is a special form of implicit
statement that “turns off” all implicit typing and requires that each data object be explicitly
typed. implicit none is not the default implicit environment (unfortunately); unless implicit
none is explicitly specified in the program unit, each letter in that program unit has an
associated implicit type/kind combination.1
1. An exception to the rule that “implicit none turns off all implicit typing” is in internal and
module procedures having implicit none in their hosts; such procedures may have implicit
statements defining implicit typing for part of the letters, leaving implicit none (and hence
explicit typing required) for the other letters - see chapter 9.
User-defined Data Types 17
The intrinsic types are the numeric types (integer, real, complex), the logical type, and the
character type. Each of these may be parameterized (type kinds), have intrinsically-
defined forms for constant values, and have intrinsically-defined operators and operations.
A number of intrinsic functions are defined for the intrinsic types, and user-defined func-
tions may return values of intrinsic type. Fortran 90 has user-defined types as well, called
derived types because they are derived from the intrinsic types (and other derived types);
all aspects of an intrinsic type, except type kind parameterization, may be provided for a
derived type - name, constants, operators, and functions returning derived type values.
Derived types, once defined, essentially augment the intrinsic types as the data types
available for use in a program. Two other uses of derived types are common: record struc-
tures and dynamic structures. Record structures are convenient for organizing data into
logical groups (records) for input and output and corresponding processing. Dynamic
structures, such as linked lists and binary trees, are indispensable for certain application
areas.
derived-type definitions
Unlike intrinsic types, whose definitions are intrinsic (built into the language), a derived
type must be defined. This is done by specifying its components, which are objects of
intrinsic or derived type (R422). The simplest form for such a definition is:
type type-name
component-definition ! a derived type has one or
[ component-definition ] ... ! more components - see R426
end type [ type-name ]
Each component definition is an ordinary type declaration statement, except that the only
attributes permitted are dimension and pointer. A component can be either a scalar or an
array, and derived types for recursive dynamic structures (e.g., linked lists, binary trees)
can have pointer components that have the same type as that being defined. More than one
component may be declared in the same component definition statement. Simple exam-
ples illustrating all of these possibilities:
type Point ! a type to represent points
real :: x, y ! in a two-dimensional
end type ! cartesian coordinate system
type Student
character(30) :: ID
integer :: homework(15) ! can represent up to 15 homework grades
integer :: hour_exam(3) ! and 3 hour_exam grades
integer :: final_exam
end type
18 Fortran 90 Concise Reference
type Pixel
type (Point) :: p ! the position on the screen;
integer :: R, G, B ! primary color values for this point
end type
The first (and last) of these four examples do indeed suggest new data types, and the
expectation would be that appropriate operations would be defined on objects of these
types. The second example suggests a typical record structure, with an expectation that
various computations would be made with individual fields (components) but not on “a
student as a whole”. The third example clearly is intended to be used as a dynamic struc-
ture, in this case a binary tree with left and right links to subtrees. The data for such a tree
can, of course, be of any nature, and in this case the details of that nature have been encap-
sulated in yet another derived type called TreeData.The fourth example also illustrates the
use of a previously-defined derived type as a type component. Though not having the
properties of true object-oriented inheritance, the Point component of Pixel does “inherit”
all of the properties (e.g., operations) defined for type Point. (In this manner, and through
use of type definitions packaged in modules, Fortran 90 provides much of the inheritance
and data abstraction benefits of object-oriented programming; typical O-O features not
accommodated are polymorphism and object invocation of procedures.)
The name of a derived type must not be the same as any intrinsic type name, nor the same
as any other derived type accessible in that scope; it also must not be the same as any vari-
able or procedure name accessible in that scope. Derived-type definitions are local to the
scope in which they are defined, but may be accessible to other scopes via use and host
association.
Component names have a scope of their derived-type definition, though they are accessi-
ble outside the type definition when (and only when) selected with the % component
selection operator (see below). Within a given type definition, each component name must
be unique, but otherwise there is no restriction on component names; in particular, they
can be the same as the names of entities defined in or accessible to the surrounding scope
of the type definition.
derived-type objects
Derived-type definitions do not create data objects; a type definition only specifies the
name of the type (analogous to, say, the type name integer) and the component structure
for objects of that type. Actual objects must be created, again in analogy with intrinsic
types, in type declaration statements (R501); derived type objects are created with a type-
spec of
type ( type-name )
User-defined Data Types 19
As with objects of intrinsic type, a derived type object, also called a structure or struc-
tured object, may be: declared as a constant (have the parameter attribute), an array (have
the dimension attribute and, optionally, be an allocatable or pointer array), a dummy argu-
ment (and, optionally, have the intent and/or the optional attributes), a module object (and,
optionally, have the private or public attribute), a pointer or a pointee (have the pointer or
target attribute), a saved local variable (have the save attribute). Function results may be
declared to be of derived type, in which case either the type ( type-name ) type specifier
may appear on the function statement or the function may be typed in the func-
tion’s specification part.
Some example declarations of derived-type objects:
type (Point) :: p1, p2
A structure reference may appear in an expression, on the left hand side of an assignment
statement, and as an actual argument - as may a component reference. A component of a
structure may be referenced by using the component access operator, %, in the following
manner (R612):
structure-reference % component
Specific examples of component references (using the above example type definitions and
structure object declarations) are:
p1 % x ! the x component of p1, a scalar real object
The last of these examples illustrates that if a structure component is itself a structured
object, then its components may be accessed as well. Such a sequence of % operators may
be of any length, as long the entity on the left of each % is of derived type and the entity on
the right is a component of that derived type; the “parsing” of such a sequence is from left
to right. The very left one must be a structured object, and is either its declared name or (if
the structure is an array) an element or section of that array. Each entity on the right of a %
operator must be either a component name or (if the component is an array) an element or
section of that array. Any array name (whole array) or array section in a component refer-
ence makes the result of the reference array valued, with the same shape; there can be at
most one array-valued entity in a given component reference.
structure constructors
A structured object may be assigned a value by individually assigning a value to each of
its components. For example:
p2 % x = 112.2 ! these two assignments
The effect of this last assignment is the same as the preceding individual component
assignments; a structure value of a given type may be assigned to a derived-type variable
of that type. (But this intrinsically-defined assignment may be overridden by a defined
assignment - see chapter 20).
The structure value Point ( 112.2, 35.7 ) is a constant because all of the component values
are constants. Such a value may be used to establish a named constant of derived type:
type (Point), parameter :: origin = Point (0.0, 0.0)
In general, however, any expressions may be used for the component values in a structure
constructor, so long as the constructor contains an assignment-compatible value for each
component, in the order in which the components are declared in the type definition.
An associated structure constructor is available for any defined or accessible type, (except
for types with private components - see below). If a type has a pointer component (either
User-defined Data Types 21
scalar or array) an allowable target object must appear in the corresponding position in a
constructor for that type. If a component is an explicit-shape array (the only type allowed
as a component other than a pointer array), an array value with that shape must appear in
the corresponding position in a structure constructor.
Additional examples of structure constructors are:
Point (z+1, w-2)
In the last example hw must be a two-dimensional integer array with a size of 15 in its sec-
ond dimension, and e1, e2, e3 and fe must all be scalar integer variables (or named con-
stants). The first three of these examples illustrate the use of arbitrary expressions to
specify component values in a structure constructor.
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
Structure values may also be obtained from input. A structure variable name may appear
in the input list of a read statement, in which case a value is input for each component. In
list directed input the effect is the same as if the individual components had been placed
(with the % operator) in the input list instead. For formatted input, a format is specified for
each component, in component-declaration order, in exactly the same manner as for the
intrinsic type complex.
read *, p1 ! read two real values, one for p1%x and one for p1%y
read “(2F10.2)”, p1
Similarly, structure values may be placed in the output list of a print or write statement,
and the component values are output in component-declaration order. Structures with
pointer components can be neither input nor output, though individual nonpointer compo-
nents of such structures can appear in I/O lists.
derived-type operators
Since dummy arguments may be of derived type, and functions may return structure val-
ues, functions may be used to define virtually any operation on and among structured
objects. For example, the midpoint between two Point objects may be defined as follows:
type (Point) function midpoint(a,b); type (Point) :: a, b
midpoint = Point ( (a%x+b%x)/2, (a%y+b%y)/2) )
end function
22 Fortran 90 Concise Reference
Note that the midpoint is, of course, a Point value. An operator, say .mid., can be associ-
ated with this operation:
interface operator (.mid.)
module procedure midpoint ! assuming midpoint is an accessible module procedure
end interface
Then the midpoint of two points, say p1 and p2, can be computed with the expression
p1.mid.p2 ! as well as with the function call: midpoint(p1,p2)
Chapter 20 contains more details on defining operators. Chapter 19 illustrates how a mod-
ule can be used to encapsulate a derived-type definition, its constants, and any operations,
so that the type could be used almost as naturally as an intrinsic type.
private types
Sometimes it is desirable to hide the internal structure of objects and access components
only via explicitly provided procedures. This is possible only for derived types defined in
modules. A derived-type’s components are accessible anywhere inside the module in
which the type is defined, but the internal structure of a private type can be hidden from
users of the module. This is accomplished with the derived-type private statement, an
example of which is:
type Point; private
real :: x, y
end type
In this case users of the module which contains this type definition can declare objects of
type Point, but cannot use the % operator to access either the x component or the y compo-
nent of those objects, nor is the Point structure constructor accessible to the user of the
module. The module may contain functions to access x and y, but need not if the intended
use of Point does not involve the user accessing the components. In this latter case the
module presumably includes procedures that provide the intended computations on and
with Point objects.
The private statement, if used, immediately follows the type statement (R422, R423) and
hides all of the components from users of the module containing the derived-type defini-
tion. Note that
type type-name; private
is really two statements, and many programmers prefer to put them on separate lines,
whereas
type, private :: type-name
is a single statement that makes the entire type, name as well as the components, private to
the module and not accessible to users of the module.
User-defined Data Types 23
sequence types
A derived-type actual argument must be exactly the same type as the associated dummy
argument or an equivalent type. “Same type” means that both a dummy and its associated
actual argument derive from the same type definition. For all practical purposes this
means that the derived type must be defined in a module that is used by, or host to, (a) any
procedure definition with arguments of that type and (b) any program unit making calls to
such procedures. (The only way the requisite conditions can be met without a module is if
all of the procedures having an argument of this type are internal procedures in a host pro-
cedure containing the type definition.)
“Equivalent types” are sequenced type definitions with the same type and the same num-
ber of components; corresponding components in each list must have the same name, the
same or equivalent type, the same attributes (dimension and/or pointer), and neither can be
private. An example of a sequence type is
type Student; sequence
character (30) :: ID
integer :: homework(15), hour_exam(3), final_exam
end type
This type definition need not be used from a module and can be repeated in any scope
which has actual or dummy arguments of type Student. The main problem with such
duplication is, of course, the maintenance one of needing to make a change in more than
one place. This problem can be circumvented by putting the sequenced type definition in
its own file and including that file wherever the type definition is needed; this, however, is
not much different from putting the type definition in a module and using the module
wherever the type definition is needed.
A derived type is made into a sequenced type by inserting a sequence statement between
the type statement and the list of component definitions (R422, 423). There is one use of
sequence types other than for equivalent type argument association. This is to allow
derived-type objects to be associated (e.g., in common blocks) with numeric or character
storage sequences. If all of the components of a sequence derived type have numeric stor-
age units (i.e., they comprise only intrinsic kinds of integer, real, complex, and logical
components), the type is a numeric sequence type and can be storage associated with any
numeric storage sequence. Similarly, if all of the components of a sequence derived type
are of type default character, the derived type is a character sequence type and can be stor-
age associated with any character storage sequence.
24 Fortran 90 Concise Reference
Arrays 25
4 Arrays
The array features of Fortran 90 represent one of the most significant aspects of the lan-
guage. A computation can be specified on a whole array (or any portion of an array); such
a computation is performed on each element of the array, conceptually concurrently. The
corresponding potential for actual process parallelism is enormous - namely the number of
elements in the array. Roughly speaking, versions of Fortran prior to Fortran 90 allowed
the programmer to specify computations only on scalar entities, such as individual array
elements, with an entire array processed by sequencing (looping) through its elements.
array-valued expressions
Suppose that A, B, and C are two-dimensional real arrays, all dimensioned at 200x300 ele-
ments. Fortran 90 allows the following statement, involving the addition of two of these
arrays and the assignment of the result:
C=A+B
The meaning of this operation is C(i,j) = A(i,j) + B(i,j) for all 200 values of i and all 300 val-
ues of j, for a total of 60,000 individual (scalar) computations involving the array ele-
ments. The array computational model is concurrent element-by-corresponding-element
computation for all elements of the arrays.
In addition to extending all of Fortran’s scalar operations to arrays in this manner, other
useful whole array operations are provided. These include reduction operations (e.g.,
product(A) returns the product of all the elements of array A), construction operations
(e.g., (/ (i, i=1,n) /) constructs the vector [ 1, 2, 3, ..., n ], and inquiry operations (e.g.,
shape(B) returns the shape of array B - a vector comprising the size of each dimension of
array B, or [ 200, 300 ] for the array B in the above example). All such operations can be
combined into more complex expressions; for example, product(shape(B)) has the value
60,000, the total number of elements in B (but Fortran 90’s rich supply of array functions
also includes the size intrinsic function, which gives the same result more directly).
Generally speaking, except in a few contexts in which an expression is restricted to be sca-
lar, any Fortran 90 expression may have array operands and the result is array valued.
(Scalar expressions are required in control contexts such as if construct control (scalar log-
ical expressions required), do loop indexing expressions, and I/O specifiers such as unit
number, file names, open statement specifiers, etc.) In most cases the arrays in an array-
valued expression must have the same shape (must be conformable) and the expression
value is an array of the same shape.
Note that in many cases, such as in the above example (C = A + B), array expressions
appear indistinquishable from scalar expressions and one needs to know from other con-
texts (e.g., the specifications) that the variables have been declared as arrays. However,
Fortran 90 allows such expressions to be written with explicit dimensionality, which
clearly identifies array operations. For example, the above assignment can be written as:
C(:,:) = A(:,:) + B(:,:) ! makes the “arrayness” explicit
26 Fortran 90 Concise Reference
Functions may be defined to return array values (array-valued functions) and calls to such
functions may be operands in array-valued expressions. Array-valued functions, including
both user-defined and intrinsic ones, make array-valued expressions a complete, natural
extension/generalization of scalar expressions, with arrays replacing scalars as operands
and results.
2 3 5 + 10 12 5 = 12 15 10
1 7 4 2 14 12 3 21 16
Note that, for example, a 3x2 array is not conformable with a 2x3 array - they have the
same rank and total number of elements, but corresponding dimensions don’t have the
same size - and thus two such arrays cannot be the operands in the same array operation.
The only exception to this basic conformability rule is in the event that one of the operands
is a scalar. In this case the scalar is broadcast into an array conformable with the other
operand, the value of each element of this broadcast array being that of the scalar. For
example, B + 2 is a valid array operation and (assuming B is as given above)
This last example illustrates a key aspect of the Fortran array operations: in an array-val-
ued assignment the effect is as if the right-hand side array value is fully evaluated before
any assignment takes place. Otherwise it is possible (though not in this simple example)
for the right-hand-side array value to be affected before its evaluation is complete. Thus
the conceptual model is that all elements of the right-hand-side array value are computed
concurrently (or in any order) before any assignment takes place, and any implementation
is allowed that guarantees this behavior.
An example where this rule is important is in the pivoting step in Gauss elimination (see
the last example in this chapter). There the pivot row is normalized with the array opera-
tion
G(P,:) = G(P,:)/G(P,K)
G(P,:) is the Pth row of the two-dimensional array G, and G(P,K) is the pivot element; the
normalization scales the row so that the pivot element value is 1.0. Note that if the value of
this element is changed to 1.0 before the evaluation of the right-hand side is complete,
then the row is not properly normalized (a typical error in sequential scalar code). There-
fore, array operations should not be thought of as “loops” over the array elements, as a
loop implies a sequentially of the operations; in general, thinking of array operations as
loops gives incorrect results when assignment is involved. Array operations should be
thought of as integral/parallel computations.
The index-variable is a scalar integer variable serving as an iterative index in exactly the
same manner as in a do loop. The example above, (/ (i, i=1,n) /), employs an implied-do
construct in an array constructor. In general, a list of expressions can precede the indexing
in an implied-do construct; a simple example: 100 million alternating ones and zeros,
(/1,0,1,0,1,0,1,... /) can be constructed with the array constructor (/ (1,0, j=1,50000000) /).
The implied-do simply replicates the list the specified number of times, and if the index-
variable is an operand in an expression in the expression-list, each replication of that item
uses the corresponding value of the index-variable. The items in the implied-do expres-
28 Fortran 90 Concise Reference
sion-list may be any of the three forms allowed in the array constructor itself - scalar
expressions, implied-do constructs, and array expressions. The two examples above have
only simple scalar expressions in the implied-do lists.
An array expression of any dimension may appear in an array constructor. For example, if
A is a 1000*1000 array then (/ A+1.3 /) is an array constructor of one million elements,
each having a value of 1.3 more than the corresponding element value of A. The elements
of A+1.3 are placed in the array constructor in array element order; array element order is
obtained by varying the first dimension first, the second dimension next, and so on. Thus (/
A+1.3 /) is equivalent to (/ ((A(j,k)+1.3, j=1,1000), k=1,1000) /). Implied-do constructs may be
used to specify a different order of the array elements in the constructor. For example, if a
row by row vector of the elements of A+1.3 is desired, rather than the column by column of
array element order, (/ ((A(j,k)+1.3, k=1,1000), j=1,1000) /) would do the job.
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
Finally, a simple form of the reshape intrinsic function can be used to reshape the (one-
dimensional) result of an array constructor into the desired array shape:
reshape ( array-constructor , shape-vector )
where the shape-vector (which may itself be an array constructor) has one element for
each dimension of the desired array shape; the value of each shape-vector element is the
number of elements in that dimension in the target array. For example, a 1000*1000 iden-
tity matrix of can be created as the array constant named ident by the declaration
real, parameter :: ident(1000,1000) = &
reshape ( (/ (1.0, (0.0, k=1,1000), j=1,999), 1.0 /), (/ 1000,1000 /) )
Thus the array constructor, coupled with the reshape intrinsic, is an extremely powerful
tool for constructing array values, including array constants.
The where mask must be conformable with the array on the left of the assignment, which
must be conformable with the expression on the right of the assignment. For mask ele-
ments that have the value true the corresponding element assignments take place; where
the mask is false the assignment is not made. A example of masked array assignment is
where (C.gt.0) A = B/C
in which the assignment is made only for those elements of C that have a positive value.
Arrays 29
Arrays A, B, and C must all be conformable and the (array-valued) logical expression
C.gt.0 is therefore a mask conformable with these arrays.
Another simple example of the use of masked array assignment can be found in the picture
refinement program near the end of this chapter. In this case the elements of a character
array are set to # where all corresponding elements in another (conformable) array are 1:
where (picData.eq.1) picDisplay = "#"
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
Any number of array assignments that are conformable with the mask, can be placed
under the control of a single mask; in this case the where takes a block form (R739):
where ( mask )
array-assignment-1
array-assignment-2
...
end where
The forms of where described above leave unassigned some elements of the array on the
left hand side of the assignment statement. An extension of the block form of where, the
elsewhere option, specifies a value to be given to the left-hand-side array elements where
the mask is false. This takes the form (R739):
where ( mask )
array-assignment-1
array-assignment-2
...
elsewhere
array-assignment-n+1
...
end where
In this case those elements of picDisplay for which picData has a value other than one are
assigned a blank rather than the # character. This is an important form of where, because it
results in a fully defined array picDisplay that can be used in subsequent array operations.
Without the elsewhere option the array picDisplay might end up not being fully defined, in
which case it cannot be used in other array expressions.
30 Fortran 90 Concise Reference
In a call to calc3, any two-dimensional array expression (of type real) may be passed to U
and any one-dimensional array expression may be passed to V; conversely, a two-dimen-
sional real array must be passed to U and a one-dimensional real array must be passed to V.
In effect the colons in the declarations for U and V instruct calc3 to accept the descriptor
information supplied by the calling program. U and V then exactly represent the corre-
sponding array objects in the actual argument list and may be used in array operations in
the body of calc3.
Assumed-shape dummy arguments require explicit interfaces (see chapter 9). This
requirement is automatically met for internal and module procedures; an interface block
must be supplied for an external procedure, however. When the procedure’s interface is
explicit, the calling program knows when an assumed-shape dummy argument is the
receiver and can then pass an efficient descriptor; otherwise the calling program cannot
assume the dummy arguments are assumed-shape and must therefore provide a contiguous
actual argument, packing and unpacking the actual argument array(s) as necessary.
where the number of subscripts is the rank of the array and each subscript is a scalar inte-
ger expression (scalar subscript). An array section is specified by replacing at least one
scalar subscript by a vector subscript (R618). A vector subscript is a one-dimensional
array of scalar subscript values for that dimension; a vector subscript may be constructed
with an array constructor. If (only) one scalar subscript is replaced by a vector subscript
the resulting array section is a one-dimensional array; if two scalar subscripts are replaced
by vector subscripts the result is a two-dimensional array, and so on. An array section has
a rank equal to the number of vector subscripts used to specify it.
As an example, consider the following 5x6 array, Q. Three sections of Q are shown in
bold: the entire second column (a one-dimensional section), the 2x2 upper right hand cor-
ner of Q (a two-dimensional section), and the last half of the fifth row of Q (a one-dimen-
sional section).
13 11 25 2 1 9
9 3 31 14 52 27
Q = 16 45 54 36 15 20
7 20 18 19 8 19
37 56 54 66 77 90
Q( :, 2 ) == (/11,3,45,20,56/) ! the second column
Q( (/1,2/), (/5,6/) ) == reshape( (/1,52,9,27/), (/2,2/) ) ! upper right corner
Q( 5, (/4,5,6/) ) == (/66,77,90/) ! last part of 5th row
Note that all of these vector subscripts could be written with implied-do constructs:
Q( (/(k, k=1,5)/), 2 ) ! the second column
Q( (/(k, k=1,2)/), (/(k, k=5,6)/) ) ! the upper right corner
Q( 5, (/(k, k=4,6)/) ) ! last part of 5th row
The implied-do form is more extensible and, for large sections, considerably more com-
pact than explicit lists. Implied-do constructs are also useful for regularly-spaced but non-
contiguous vector subscripts. For example,
Q( (/(k, k=1,5,2)/), 2) == Q( (/1,3,5/), 2 ) == (/11,45,56/)
The implied-do form is common enough that a more readable shorthand notation, called a
triplet subscript (R619), is also provided for the indexed-do control triplet.
A triplet subscript is just the indexed-do control values, separated by colons rather than
commas, with the last one (the increment or stride value) optional. Thus using triplet nota-
tion the above four examples may be written (much more clearly!) as:
Q( 1:5, 2 ) or Q( :, 2 ) ! the second column
Q( 1:2, 5:6 ) or Q( :2, 5: ) ! the upper right corner
Q( 5, 4:6 ) or Q( 5, 4: ) ! last part of 5th row
Q( 1:5:2, 2 ) or Q( : :2, 2 ) ! every other element of 2nd col.
(The form Q(:,:) is a section that comprises the entire array Q. This form in a dummy argu-
ment declaration, rather than in an array expression, specifies an assumed shape dummy.)
32 Fortran 90 Concise Reference
Though the above examples employ array constructors, any one-dimensional integer array
expression is permitted as a vector subscript. The only requirement is that the value of
each element of the vector subscript be a valid subscript value for that dimension of the
array. A common form for vector subscripts is a one-dimensional integer array name (or
section), whose element values have been previously established. This form is useful for
indirect access, such as indexing into a table; e.g., table elements may be retrieved (or set)
by subscripting the table array with an array containing the desired table index values.
For the array Q defined above, for example, consider Q( (/2,5,3/), (/6,4/) )
Q Q
2, 6 2, 4 27 14
This represents the array section Q
5, 6
Q
5, 4 = 90 66
Q Q 20 36
3, 6 3, 4
This section can be used in any array expression in which a 3x2 array object is valid. It
may also appear on the left hand side of an array assignment, in which case the (1,1) ele-
ment of the right hand side expression value gets assigned to Q2,6, the (3,2) value of the
right hand side gets assigned to Q3,4, and so on.
A vector subscript may contain more elements than the size of that array dimension. In
this case there are duplicate values, since all of the values must be within the array dimen-
sion range. Indeed, subscript values may be duplicated in a vector subscript even if the
size of the vector is less than the array dimension (the only requirement is that the sub-
script values must be within range). Both of these cases are illustrated in the following
example, which specifies a 7x4 section from the elements of Q.
Q Q Q Q
4, 1 4, 4 4, 4 4, 3
Q Q Q Q
1, 1 1, 4 1, 4 1, 3
Q Q Q Q
2, 1 2, 4 2, 4 2, 3
Q ( ( /4,1,2,3,4,2,5/ ), ( /1,4,4,3 ) ) = Q 3, 1 Q 3, 4 Q 3, 4 Q 3, 3
Q Q Q Q
4, 1 4, 4 4, 4 4, 3
Q Q Q Q
2, 1 2, 4 2, 4 2, 3
Q Q Q Q
5, 1 5, 4 5, 4 5, 3
Note that rows one and five of this section are identical, as are rows three and six and col-
umns two and three. Many elements of Q therefore appear twice in this array section and
two elements, Q2,4 and Q4,4, each appear four times. Array sections with multiple appear-
ances of a given parent array element are perfectly legitimate array operands in array
expressions, but such sections must not appear on the left hand side of array assignments
(or be actual arguments associated with intent(out) dummy arguments - see chapter 9).
Arrays 33
dynamic arrays
Fortran 90 has three varieties of dynamic arrays. All three allow array creation at run time
with sizes determined by computed (or input) values. The three varieties are: automatic
arrays, allocatable arrays, and pointer arrays.
automatic arrays: Automatic arrays are local arrays whose sizes depend upon values asso-
ciated with dummy arguments. Automatic arrays are automatically created (allocated)
upon entry to the procedure and automatically deallocated upon exit from the procedure.
The size of an automatic array typically is different in different calls to the procedure.
Examples of automatic arrays are:
function F18(A,N)
integer N ! a scalar
real A(:,:) ! an assumed shape array
real F18(size(A,1)) ! the function result itself is an automatic array
Note the importance of the intrinsic inquiry functions, such as size in declaring automatic
arrays; a number of inquiry functions are provided that are allowed to appear in declara-
tions. Array bounds and sizes, character lengths, and type kinds may all be specified with
expressions involving these inquiry functions. Roughly, a specification expression, as such
expressions are called, is a scalar integer expression that has operands whose values are
determinable upon entry to the procedure. Such operands include constants, references to
certain intrinsic procedures, and variables accessible through dummy arguments, modules,
common, and (in the case of module and internal procedures) the host procedure.
allocatable arrays: Allocatable arrays are those explicitly declared allocatable. An allocat-
able array may be local to a procedure or may be placed in a module and effectively be
global to all procedures of the application. An allocatable array is explicitly allocated with
the allocate statement, and deallocated either explicitly with the deallocate statement or, if
it is a local array for which save has not been specified, automatically upon exit from the
procedure. (If save has been specified, local allocatable arrays can persist from one execu-
tion of the procedure to the next - they must be explicitly deallocated with a deallocate
statement.) A global allocatable array persists until it is explicitly deallocated, which may
occur in a procedure different from the one in which it was allocated. An allocatable (or
pointer) array is indicated if its size depends on a value to be computed after its declara-
tion. The allocation status (allocated or not yet allocated) of an allocatable array may be
tested with the allocated intrinsic function. Examples of allocatable arrays are:
34 Fortran 90 Concise Reference
subroutine Peach
use Recipe ! accesses global allocatable array, Jam
real, allocable :: Pie(:,:) ! Pie is a 2-dimensional allocatable array
...
Note that the declared bounds for allocatable arrays are simply colons, indicating that
these will be provided later, at the time of allocation. This makes allocatable array declara-
tion appear similar to assumed-shape dummy argument declaration, appropriate because
the “deferred” nature of the sizes of the dimensions is conceptually similar.
pointer arrays: Pointer arrays are similar to allocatable arrays in that they are explicitly
allocated with the allocate statement to have computed sizes and are explicitly deallocated
with the deallocate statement. Simple examples of pointer arrays result by replacing allo-
catable with pointer in the preceding examples of allocatable arrays.
In addition, pointer arrays can be used as aliases for (may point to) other arrays and array
sections; the pointer assignment statement is used to establish such aliases. The target for
pointer associations (as such aliasing is called) may be other explicitly allocated arrays, or
static or automatic arrays that have been explicitly identified as allowable targets for point-
ers. The association status of a pointer array may be tested with the associated intrinsic
function. Pointer arrays may be dummy arguments and structure components, neither of
which are allowed for allocatable arrays.
Given this apparent similarity between allocatable arrays and pointer arrays, what is the
fundamental distinction between these two forms of dynamic arrays, and when should
allocatable arrays be used rather than pointer arrays? Pointer arrays subsume all of the
functionality of allocatable arrays, and in this sense allocatable arrays are never needed -
pointer arrays could always suffice. The problem with pointer arrays is efficiency. Though
pointer arrays must always point to explicit targets, which makes some optimization prac-
tical that would otherwise be infeasible, pointer assignment makes optimization of pointer
arrays much more difficult than for allocatable arrays. Because of their more limited
nature and functionality, allocatable arrays are just “simpler” and can be expected to be
more efficient than pointer arrays.
Therefore, when all that is needed is simple dynamic allocation and deallocation of arrays,
and automatic arrays are not sufficient, use allocatable arrays. A common example of this
is if a “work array” is needed of a size dependent upon the results of a local computation.
If, on the other hand, the algorithm calls for a dynamic alias, of for example a “moving”
section of a host array, then a pointer array is probably indicated.
Arrays 35
array-valued functions
As noted above, functions can be defined that return array-valued results. In addition, most
intrinsic functions can return array values (and some always do). Array-valued functions
may be used as operands in array-valued expressions, allowing more forms of concurrent
computation expression.
An example using an array-valued intrinsic function is common in applications of finite
difference modeling. Here each element of a large two-dimensional array g is to be added
to the “next” element in the same row of a conformable array u, and subtracted from this is
the “previous” row element of u; this is to be done with all of the elements of g, resulting
in a conformable array r. The computation, for each element, is sketched as follows:
g α
u β γ
α+β−γ
Using the cshift intrinsic function, which returns a given array “shifted” a specified
amount, this computation is nicely expressed as follows:
r = g + cshift(u,1, 2) - cshift(u,-1, 2)
This illustrates the power of array-valued functions, especially if g were replaced with an
array-valued function reference rather than an array variable reference.
The array-valued intrinsic functions are all summarized at the end of chapter 9 and
described in detail in chapter 10. Function F18 in the previous section and the functional
form of g in the preceding example are examples of user-defined array-valued functions.
The shape of the result returned by user-defined array-valued functions normally is deter-
mined (dynamically) from arguments, as illustrated in the F18 example (and see the Refine
and Solve examples below). Note that function results are declared to be array-valued with
ordinary declaration statements, as if the function name is an ordinary variable (as indeed
it is within the body of the function). Though automatic arrays may be the most useful
form for user-defined array-valued functions, any other form is also valid: explicit-shape
array, allocatable array, pointer array.
The main additional requirement for user-defined array-valued functions is that the array
value must be fully defined before completeion of execution of the function. On the caller
side, the interface of an array-valued function must be explicit so that the caller knows that
it is dealing with a function that is array-valued; otherwise the caller has to assume the
function returns a scalar value, which is then broadcast in the array-valued expression
from which the function is called.
36 Fortran 90 Concise Reference
contains
!--------------------------------------------------------
function display(pic); integer :: pic(:,:) ! assumed shape argument
character :: display(size(pic,1),size(pic,2)) ! returned value same size
## # #
# #
############## ############# ############# #########################################
######################### ############### ## ## ############################################
### ##### ##### ##### #####
### # # #### #### ####
#### #### # #### #### # ### ### ### ####
# ## # # ## # # ### ## ##### #### #### ##### ####
##### #### ###### ## # #### ### ##### ####
# #### # # ##### #### ####
#### ## # ## # #### # #### ####
# # ## # # #### #### ####
#### ### ### #### # #### # # ####
# #### ### # # # # ### #### #### ### ####
# #### ##### ########### #### #### # #### #### ################ ####
#### # ###### ######### ## # ## #### # ############### ####
#### #### #### ####
### # # ##### # ##### #####
## ########### ##################### ########## ############################################
##################### #################### # ##########################################
# # ##
# ##
Program Refine defines two array-valued functions, both with assumed-shape dummy
arguments whose size determines the returned array size. Function display illustrates the
use of the where construct. Function refined illustrates (a) the use of an array intrinsic
(size) in the execution part as well as in the specification part, (b) assigning a value to an
array section, and (c) a nontrivial array-valued expression which exhibits considerable
conceptual concurrent computations.
end function
end program
When executed with the simple data sets shown above, this program returns (1.0, -1.0, 2.0)
and (7.0, -2.0) for the respective solution vectors, demonstrating that function Gauss will
correctly solve any size linear system. The entire matrix is reduced for each pivot, rather
than just those columns needing reduction, so that about twice as many (scalar element)
operations are performed as are really necessary; further tailoring of the not_pivot_row
mask could decrease the number of (scalar) operations. Note that, in terms of the number
of array operations, more attention is devoted in Gauss to preparing the masks than to the
numerical computations themselves - in array algorithms logical masks take the place of
conditional statements in sequential scalar algorithms.
The Gauss code is pretty straightforward (though reading and writing such compact,
highly concurrent array operations code takes some getting used to); perhaps the least
obvious aspect of Gauss is its use if the spread intrinsic function. spread replicates
(spreads) a scalar into a one-dimensional array, or replicates an n-dimensional array into
an n+1-dimensional array. The scalar-to-one-dimensional array form is used in Gauss to
convert the scalar operation G(i,j)=G(i,k)*G(k,j), where k is a constant, into a whole-array
operation (over all i and j) on G. spread has three arguments: the first is the scalar or array
value to be spread, the second is the dimension over which the spreading occurs (and must
be one for spreading a scalar), and the third is the number of replications.
Function Gauss has, for any given system size n, of the order of: 7n array masking opera-
tions and 7n array numerical computations, corresponding to about n4 scalar logical oper-
ations and 7n3 scalar numerical operations. As the “cost” (execution time) of an array
operation, continues its inexorable march toward that of a scalar operation, array codes
such as Gauss become increasingly attractive in terms of performance.
Redundancy 39
5 Redundancy
Some of the newer features of Fortran, motivated by modern common programming prac-
tices, have made some of the earlier features redundant. The purpose of this chapter is to
identify and summarize these redundancies.
The current Fortran standard officially identifies “two categories of outmoded features”:
(1) those for which “better methods existed in Fortran 77” and (2) those for which “better
methods exist in Fortran 90”. The standard goes on to say “programmers should use these
better methods ...”. In this reference these two categories are called “deprecated” (out of
favor) features.
In addition to those officially deprecated, there are several features of Fortran 90 that are
redundant and for which many believe that “better methods exist”: common, equivalence,
and attribute specification statements.
common blocks
Before Fortran 90, the only practical way to provide for global objects (variables and con-
stants) was via common blocks; because global objects are important to many Fortran
application areas, much practical pre-Fortran-90 code uses common. Common blocks are
contiguous blocks of storage, and an object may be associated with (occupy) certain stor-
age units in a common block. Any program unit can access a given common block and
thereby access an object by virtue of its known location in the common block. Such
objects are said to be storage associated, and common blocks share objects among pro-
gram units through storage association.
Common blocks are distinguished by (programmer-specified) names, and the common
statement (R548) allows the programmer to declare a common block having a given name.
The common statement also specifies a sequence of objects that are associated with the
successive storage units of that common block; the common block can contain any mix of
scalar and array variables (R549), but cannot contain an allocatable array, a dummy argu-
ment, a nonsequence structure, or a function result name; arrays dimensioned in common
block arrays must have constant bounds. In a given program unit, a object cannot be
assigned to two (or more) common blocks.
The common block names are themselves global, known to all program units. Two (or
more) program units accessing the same common block access the same sequence of stor-
age units; the object names and mix may be different in the two program units - the associ-
ation is by storage sequence. For example, suppose that two program units specify the
same common block as follows (where all the variables are of type default real):
common / Omega / x(100), y, z(200)
The common block name is Omega and it contains 301 storage numeric units. In one of
the program units the first 100 storage units of Omega are known as the array x, the 101st
40 Fortran 90 Concise Reference
is the scalar y, and the last 200 are the array z; in the second program the first 200 storage
units are known as the array a, the next 100 storage units are known as the array b, and the
last storage unit is know as the scalar variable c; y and a(101), for example, represent the
same storage location and hence are the same “thing”.
Objects of type default integer, default real, and default logical have numeric storage
units; objects of type default complex and double precision real each require two numeric
storage units and double precision real requires four numeric storage units. Objects of type
default character have character storage units. Every other type/kind combination (or
type/kind/rank combination for pointers) has a different, unique (but unspecified) storage
unit. Objects with different storage units maybe be placed in a given common block, but
each program unit in a program using that common block must specify exactly the same
sequence of storage units. If a sequenced structure appears in a common block, the effect
is as if the individual components, in order, had been placed in the common block.
Because of the strict requirement of the preceding paragraph, a popular use of include
lines (before the advent of modules in Fortran) was to make one copy of a common block,
place it in a file, and include that file in every program unit that used that common block.
With modules, the same effect can be achieved by placing the common block in a module
and using that module. Even better (and simpler), place the variable definitions directly in
the module, without putting them in common blocks; those variables are then global to all
programs units using that module (see chapter 8).
Two or more common statements naming the same common block can appear in the same
program unit; the effect of the second (and subsequent) statements is to extend the com-
mon block defined in the first such statement. A named common block must have the same
size in all program units. A common block name may appear in a save statement, in which
case the entire block is saved; individual variables in a common block must not have the
save attribute. Variables in a named common block may be initialized in a block data pro-
gram unit.
The common block name may be omitted in a common statement, in which case the com-
mon block is known as blank common. There may be any number of named common
blocks, but there is only one blank common; multiple blank common statements in a pro-
gram unit simply extend the one blank common. The rules for blank common are the same
as for named common, except that blank common is always saved, blank common vari-
ables cannot be initialized, and different program units can specify blank commons of dif-
ferent sizes (but storage units must still be associated with like storage units).
equivalence
To save space, two or more variables may share the same storage; the equivalence state-
ment is how such sharing is specified. This was important when computing systems had
quite limited storage, but equivalence is largely redundant these days because there is not
normally now the overpowering need to “save space”.
Two (or more) variables are equivalence objects (share the same space) if they appear in
an equivalence-set of an equivalence statement (R545-547). An equivalence object may be
Redundancy 41
a variable name (scalar or array), an array element, or a substring; it may not be a named
constant, an allocatable array, a dummy argument, a nonsequence structure, a function
result name, a pointer (or structure containing a pointer), or any part thereof. There must
be at least two equivalence objects in an equivalence set and all equivalence objects in an
equivalence set must be of like storage unit. An example of an equivalence statement is:
equivalence ( x, b(10,20) ), ( first, name )
In this case the variable x is the same as the array element a(10,20), assuming that x is a
scalar real and b is and array of reals, and changing one changes the other; if first is a sin-
gle-character variable and name is a longer character string, this equivalence statement
causes first to be the same character (share the same character storage unit) as the first
character of name.
Equivalence superimposes (makes the same) two or more storage unit sequences; thus
unlike storage units cannot be equivalenced. Moreover since arrays and array element may
be equivalence objects, and (whole) arrays occupy contiguous storage units, care must be
taken to not specify inconsistent pairings. For example, if x and y are both one-dimen-
sional real arrays
equivalence ( x(10), y(20) )
specifies inconsistent offsetting and hence is illegal. As illustrated, any array elements or
substrings specified as equivalence objects must use constants as the subscripts or sub-
string ranges. An unsubscripted array name (or a character variable name) as an equiva-
lence object, storage associates the first element of the array (or first character of the
string) to the other equivalence objects in that equivalence set.
The objects in an equivalence set must be local to that program unit. An equivalence object
may be a variable in a common block, but equivalence must not cause two different com-
mon blocks to become storage associated, nor add storage units that precede the front of a
common block.
attribute statements
Prior to Fortran 90 Fortran did not have the attribute form of the type declaration statement
(see chapter 2); separate statements, now called attribute statements, were used to convey
attributes to objects; each such statement conveys exactly one such attribute. Though the
attribute form of the type declaration makes the attribute statements essentially redundant,
attribute statements are the only way attributes can be given to implicitly typed objects.
Constraints pertaining to attributes are summarized in chapter 2.
The typical (but not only) form for attribute statements is
attribute-name [ :: ] object-list
The effect is that the named attribute is given to each of the object listed in the object list.
42 Fortran 90 Concise Reference
In the first of these, which is not of the general form given above, MAX may be implicitly
typed; in the second, the (two) variables are explicitly typed, but the other attributes are
conveyed with separate attribute statements. The attribute statements having precisely the
form shown above are: the optional statement (R520), the dimension statement (R525), the
allocatable statement (R526), the pointer statement (R527), the target statement (R528),
the external statement (R1207), and the intrinsic statement (R1208).
The attribute statements having almost the form shown above are: the intent statement
(R519), the public and private statements (R521), and the save statement (R523). In the
intent statement, an intent-spec (R511) must follow the intent keyword. In the public, pri-
vate, and save statements, the object-list is optional; if it is missing then the attribute
applies to all of the local objects with which it is compatible. Note that the save attribute
statement is the only mechanism for saving a named common block.
The form of the parameter statement is given in R538-539; such a statement can contain
any number of named constant value definitions, separated by commas and enclosed in
parentheses. Another example of a parameter statement is:
parameter ( MAX=100, DOUBLE=kind(1D0) ) ) ! assuming DOUBLE is of type integer
The data statement (R529-537), which initializes variables, not constants, is the attribute
statement that differs the most from the general form; it also is the one that is almost not
redundant, as it can be used to initialize part of an array, a structure, or a substring (the ini-
tialization provision of the type declaration, when applied to an array, structured object, or
a character string, must initialize the entire array, structure, or string).
The simplest form of the data statement is:
data variable-list / value-list /
The variables in the variable list are “paired”, left to right, with the values in the value list;
each value has to be assignment-compatible with its associated variable. Any substring or
array section ranges, or array element subscripts, in the variable list must be constants, and
all values in the value list must be constants and any repeat factors must be positive integer
constants. An example of a data statement is:
data count, n, name(1:3), (x(i), i=4,19,3) / 0, 0, "Dru", 6*3.5 /
After the data keyword comes the list of variables to be initialized; between the slashes (/)
are the initial values. In this case the variables are scalar integers count and n, both initial-
ized to zero, a substring (first three characters) of character variable name, initialized to
"Dru", and six elements (4,7,10,13,16,19) of real array x all initialized to the value 3.5.
The 6 in 6*3.5 is a repeat factor and 6*3.5 is equivalent to 3.5,3.5,3.5,3.5,3.5,3.5.
Redundancy 43
Recall that an object with the data attribute (i.e., has been initialized) also automatically
has the save attribute. The following objects must not appear in a data statement: a named
constant, an object in common (unless the data statement is in a block data program unit)
an allocatable array, a dummy argument, a function result name, a pointer (or structure
containing a pointer), or any variable imported by host or use association.
deprecated features
The Fortran standard says that deprecated features may be removed from subsequent ver-
sions of the standard. Even should this happen, standard-conforming implementations are
still allowed to support these features (as “extensions” to the language); many will do so.
The five deprecated features for which the standard proclaims there are “better methods in
Fortran 77” are:
1.1 real (and double precision) do control variables (R822)
This tends to be error-prone because of accumulated round-off error
associated with repeated arithmetical operations. The better method is to
use an integer control variable and to convert it to the requisite real value
prior to using it in the computations of the loop.
1.2 branching to an end if statement (from outside that if construct)
Better method - branch to the statement following the end if.
44 Fortran 90 Concise Reference
6 Input/Output
Just as Fortran has an entire “sublanguage” for array processing (see chapter 4), so too
does it have a comprehensive sublanguage for performing data input and data output.
The read statement performs data input. The sources for data input are the user’s keyboard
and/or one or more data files on the computing system; the input process transfers a copy
of the data from the external source(s) into specified variables of the program, replacing
the previous values of those variables. The write statement performs data output. The des-
tinations for data output are the user’s screen and/or one or more data files; the output pro-
cess transfers a copy of the values of specified variables and expressions to the external
destinations, either appending the data to previously written data or replacing existing data
on the external destination(s), depending on the nature of that particular output operation.
Fortran I/O is record oriented. A data file is a sequence of records, each record being a
sequence of values terminated by a special end-of-record (EOR) character (or character
combination). EOR is system-dependent but often is equivalent to end-of-line - when dis-
played on a screen, each line represents a record. A read statement normally “consumes”
an entire record (line), regardless of how much data is then actually used; a write state-
ment normally produces an entire record (including the EOR). When reading from the
keyboard each typed line, ending with the return key, is an input record; when writing to
the screen each write operation produces one line of output. Fortran 90 introduced nonad-
vancing I/O, providing Fortran, for the first time, with partial-record I/O capability.
The basic read and write statements are quite simple. The bulk of the I/O sublanguage
involves the many data formats that the input/output processes must accommodate, as well
as tools for effectively utilizing the data file system. The first two sections of this chapter
illustrate basic reading and writing of data; though relatively simple, these illustrations
include a great many practical uses of the read and write statements. The remaining sec-
tions are devoted to the more specialized, or more subtle, aspects of formats and files.
The input-list specifies the variables into which the data is to be read; the items in paren-
theses specify the data source (unit), the data format, and a status variable (to detect input
errors, end of file, etc.) - these are called the input control specifiers (R912). Note that the
only control specifier required is the unit and that the only specifier keyword required,
when that specifier is used, is iostat=. If the input list is omitted, no values are input, but a
record is consumed nonetheless.
Actual uses of the read statement tend to appear quite a bit simpler than the above general
form:
read (dataFile, fmt=* ) x, y, z ! read 3 values from a data file, with "free form" input
48 Fortran 90 Concise Reference
read (*, fmt="(I4,A)", iostat=k2) number, name ! read two values from the keyboard
read (expenses, fmt=*) balance, amounts ! read 2 values from a file; "free form" input
read (*,*, iostat=ios) next ! read one value from the keyboard
An asterisk (*) for the unit specifies keyboard input rather from a file. An asterisk for the
format specifies default formatting (also called list-directed formatting); list-directed input
formatting assumes the individual values requested (by the input-list) are separated by
(any combination of) spaces, commas, and end-of-lines. The iostat option is used if and
only if the programmer wants to detect input errors or the end of the file.
If the input unit is to be a data file rather than the keyboard, the unit is an integer value
(this is a good place to use a named constant); this value must have been connected to a
specific file, with the open statement, prior to executing the read statement. For example:
open(inputData, file="lab/test-16.data") ! inputData is a previously defined integer
After execution of this open statement the appearance of inputData as the unit in a read
statement will cause the input to be taken from the next record in the file identified as “lab/
test-16.data”, which on most systems is the file named “test-16.data” in the directory
named “lab”. The simplest form of the open statement is
open ( [ unit= ] unit , file= file-name )
where unit is as defined above for the read statement and file-name is any character expres-
sion; of course if the file specified by file-name does not exist, an I/O error occurs. See the
section below on opening files for other features of the open statement and how to prevent,
detect, and recover from I/O errors encountered while opening files.
The format specifier in the read statement may be: omitted (in which case this is a unfor-
matted read), an asterisk (listed-directed formatting, see above and the relevant section
below), a character expression (whose value must be a valid format specification, R1002),
or a label (which must be the label of a format statement, R1001). (See chapter 5 for a dep-
recated option not listed here.) The format specifies how the input data is converted and
assigned as the values of the variables in the input list. An unformatted read must specify a
unit that is connected to a file previously created with unformatted write statements.
If an iostat variable is specified in a read statement, it must be an integer variable, and after
execution of the read statement it is defined as follows: with a negative value if end-of-file
is detected (in which case no data input occurs, and the variables in the input list are unde-
fined), with a positive integer value if an I/O error occurs (also in which case the variables
are undefined), or zero (in which case no error or end-of-file occurred and the variables are
defined with the input values). The non-zero values for the iostat variable are implementa-
tion-dependent, but in principle can be used to determine the exact nature of the error.
Alternatives to the iostat= specifier are the end= specifier and the err= specifier (R912).
end= applies only to input and specifies the label to which the program branches if the
end-of-file is encountered during execution of the read statement in which the end=
Input/Output 49
appears. err= can be used with both input and output and specifies a label to which the pro-
gram branches if any I/O error occurs during execution of the read or write statement in
which the err= appears. In addition, the err= option is available in the other I/O contexts in
which iostat= can appear: the open and inquire statements. end=/err= can be used together
with iostat=, in the same statement, or they can be used separately.
The input list (R914) can contain any variables, in any order, that can appear on the left-
hand side of an assignment statement, including scalar variable names, array variable
names, array elements, array sections, substrings, and structure components; in addition,
the input list can include io-implied-do constructs (R916).
The output-list specifies the values to be copied to the output destination; the only differ-
ence between the input list and the output list is that, whereas the input list must specify
assignment-capable variables, the output list can comprise any set of expressions (includ-
ing stand-alone variables and expressions formed in io-implied do constructs). If the out-
put list is omitted, an empty record is written; on the screen this appears as a blank line.
The unit, format, and iostat specifiers in the write statement are the same as in the read
statement. The unit is an integer value that identifies the file that is to receive the output, or
it is an asterisk; if the latter, the output is displayed on the user’s screen. As for input, if the
output is to a file, the unit (integer value) must have been connected, by an open statement,
to the desired file before execution of the write statement. The simplest form of opening a
file for output appears exactly like that for input.
Also as in the read statement, the format specifier in the write statement may be: omitted
(in which case this is a unformatted write, and any subsequent reads on this file must be
unformatted), an asterisk (listed-directed, system-defined default output formats are used),
a character expression, or a label. The format specifies how the values of the output list are
to appear in the destination record. Unformatted output should not be sent to the user’s
screen.
The only role of the iostat variable in a write statement is to detect, and take corresponding
action, if an error occurs during the execution of the write statement. As in the read state-
ment, if an error occurs the iostat variable is defined with an implementation-determined
positive value; if no error occurs the iostat value is zero.
Examples of the write statement are:
write (dataFile, fmt=* ) x, y, z ! write 3 values to a data file, with default formatting
write (*, *, iostat=ios) number, name ! write two values to the screen
write (*, fmt="(T20,I5)", iostat=ios) next ! write one value to the screen
A redundant form of write(*, format ) ... is provided as the print statement (R911):
print format [ , output-list ]
Similarly, a redundant form of read(*, format ) ... is provided (R909, second alternative):
read format [ , input-list ]
data formats
Data read from the keyboard or written to the screen is always formatted; data read from
or written to a file may be either formatted or unformatted. Unformatted I/O is specified,
as outlined above, by omitting the format specifier from the io-control-list. The purpose of
unformatted I/O is to provide efficient data transfer, without conversion between the file
and the internal representation in the programs variables; in an unformatted write the bit
patterns of the data as represented in the program variables is written, unchanged to the
file. Such data is subsequently readable only by the corresponding unformatted read state-
ment (“corresponding” meaning the same type/kind pattern of variables in the input list as
values in the written by the output list), and again the bit patterns are simply transferred -
in this case from the file to the variables - without conversion. To be readable by humans,
data must be converted from internal form to appropriate character strings, and vice versa
- that is, formatted.
Default numeric types, for example, are typically groups of 32 binary bits; to be readable
by humans this the value of an real variable must be converted to the familiar decimal digit
representation of numerical values (complete with decimal points, minus signs, etc.). Sim-
ilarly, when one types a -14 as keyboard input, this must be converted to the internal (usu-
ally binary) representation used by the variable receiving this value. Formatted I/O first
specifies that such conversion is to take place and second allows the programmer to spec-
ify the exact form of the output (number of decimal places, for example) and, for input, the
exact form in which the data exists (and from which conversion must be made).
Such conversion is specified by format data edit descriptors (R1005). A format-specifica-
tion (R1002) is a sequence of such edit descriptors, delimited by commas, possibly inter-
spersed with control edit descriptors (R1010), and enclosed in parentheses. In a formatted
I/O statement each value in the input-list or output-list is “paired with” a data edit descrip-
tor that specifies how that value appears in the source (input) or how that value is to appear
in the destination (output). The association is positional, with each value in the input/out-
put list associated with the data edit descriptor in the same position (ignoring any control
edit descriptor) in the format specification - thus, in left-to-right fashion, the first value in
the input/output list is associated with the first data edit descriptor in the format specifica-
tion, the second with the second, etc. The descriptor list may be longer (have more data
edit descriptors) than the input/output list (has values), in which case the extra descriptors
are unused; if the descriptor list is shorter, then it is “reused” as often as needed. Some
examples appear above - others are:
(A8, E16.6, I10) ! a character, real, and integer, in 34 spaces
Input/Output 51
(A10, 2L5, A20, A30, F10.4) ! ( note that these five examples are
Each intrinsic data type has a set of data edit descriptors. The I, B, O, and Z data edit
descriptors are for integer values. The F, D, G E, EN, and ES data edit descriptors are for
real values (and complex values - each complex values takes two real data edit descriptors
- one for the real part and one for the imaginary part). The L edit descriptor is for logical
values, and the A edit descriptor is for character values. A derived type (structure) value
requires a set of data edit descriptors corresponding to its components, an appropriate one
for each of its (intrinsic) components, similar to complex (thinking of a complex value as a
structure with two real components). The following table summarizes these 12 data edit
descriptors:
In these data edit descriptors w, d, e, and m all must be unsigned integer constants (but not
named constants); in addition all may be optionally preceded by an unsigned integer con-
stant (but not named constant) repeat factor; the letters I, B, O, Z, F, E, D, G EN, ES, L
and A must all be capital (cannot be lowercase). All involve a field width, w, which is the
total number of characters “reserved” for this value.
The control edit descriptors, which can be inserted among the data edit descriptors as
desired, and also comma delimited, are summarized in the following table:
control edit
effect examples
descriptor
/ at this point complete the current record and start a new one; need not be comma delimited /,/
Tn tab to the character column n of the record (tabbing may be either forward or backward) T40
TL n tab left (backward) n character columns in the record TL2
TR n tab right (forward) n character columns in the record TR12
nX same as TR n 12X
S processor choice as to whether or not to output the optional plus sign (this is the default) S
SP from this point, the optional plus sign must be output; no effect on input SP
SS from this point, the optional plus sign must not be output; no effect on input SS
BN from this point, nonleading blanks in numeric input fields treated as nulls; no effect on output BN
BZ from this point, nonleading blanks in numeric input fields treated as zeros; no effect on output BZ
“scales” subsequent numerical values; on input, no effect if the input field has an exponent, and
kP otherwise divides the input value by 10**k during conversion; on output, no effect for the F, (F 3P
part of) G, EN, and ES edit descriptors, and for the E and D (and E part of G) descriptors 8P
reduces the exponent value by k and multiplies the nonexponent part by 10**k
ch-ed a character constant (but not a named constant) that is written to output; no effect on input "x= "
: stops output format processing if the output list has been finished (suppresses subsequent ch-ed) :
In these control edit descriptors k and n must be unsigned integer constants (but not named
constants); the letters P, T, L, R, X, S, N, and Z must all be capital (cannot be lowercase).
Some examples of format-specifications containing both data edit descriptors and control
edit descriptors are:
(T5, I5, I5, 2F10.2, A42) ! tab to column 5 first
(A10, 2L5, TR10, A20, A30, 2PF10.4) ! tab right after logicals, and scale the real
(A, BZ, G10.2E4, EN8.4) ! treat blanks as zeros in the two numeric fields
The discussion, tables, and examples in this section summarize most of the important con-
cepts and techniques of I/O formatting. But there are many other combinations and subt-
lies: treatment of formatting takes an entire chapter and 21 large pages in the Fortran
standard, and 53 (smaller) pages in the exhaustive Fortran 90 Handbook. Consult the ref-
erences listed in the preface for additional details regarding formatted I/O.
Input/Output 53
For those open specifiers for which character values are listed in the above table (e.g.,
action= "read"), the value can be specified as a character expression, but such expressions
must evaluate to one of the listed options, either in uppercase or lowercase (all lowercase
shown above). For those specifiers having a specific default value, the default is identified;
in the other cases the default is processor dependent. Note the one case that is incompati-
ble with the file= specifier: when status="scratch" is specified.
Some of the options in the above table involve concepts to be discussed in subsequent sec-
tions of this chapter; for example, access= "direct" specifies a “random” file rather than a
sequential file, and random files are described in section below entitled “sequential and
random files”.
The close statement (R907-908) disconnects the file currently connected to the specified
unit, allowing the unit to be reconnected later to another (or even the same) file. Any con-
nections not explicitly terminated by close statements are automatically close at the termi-
nation of the program. As with the open statement, the close statement has a list of
specifiers, only one of which is required (the unit specifier, which is the same as in the
open statement). The close err= and iostat= specifiers play the same error-handling role in
the close statement as they do in the open statement. The only other close specifier is the
status= option, which has two possible values: "keep" specifies that the file remain on the
system after being closed, and "delete" specifies that the file be deleted from the system;
"delete" is the default for scratch files and "keep" is the default for all other files.
Input/Output 55
file inquiry
The Fortran I/O sublanguage has an extensive file inquiry mechanism, which allows infor-
mation to be obtained about a file before opening it; such information can be used in sub-
sequent connection specifiers. The form of the inquire statement (R923-924) is similar to
that of the open statement in that in has a statement name and a list of specifiers; each
specifier specifies a variable to hold the returned information (except err=, which specifies
a label). As in the open statement, the only specifier for which the keyword can be omitted
is the unit specifier, and then only if this is the first specifier in the list; any given specifier
can appear at most once in a given inquire statement.
Each inquire statement must have either a unit specifier or a file= specifier but, unlike the
open statement, not both. If it has a unit specifier then the inquiry is “by unit”, and the
information returned pertains to the unit and the file connected thereto (if any). If the
inquire statement has a file= specifier then the inquiry is “by file” and the information
returned pertains to the file on the system with the name specified in the file= specifier. In
inquiry by unit the specified unit may or may not be connected; in inquiry by file the file
may or may not exist and, if it exists, may or may not be connected to a unit. the various
inquiry specifiers are summarized in the following table.
a. The value is undefined if the unit is not connected, or is connected to a scratch file.
b. If the connection is for direct access, all records have the same length;
if the connection is for sequential access, the maximum record length is returned.
Three of the inquire specifiers (unit=, file=, and err=) serve as input to the inquire state-
ment; the others all return values to the program. Three of these specifiers (named=, exist=,
and opened=) return logical values, five (number=, iostat=, recl=, nextrec=, and iolength=)
return (default) integer values, and the rest return (default) character values. Note that in a
great many cases the value return is undefined if the file or unit in not currently connected,
which means that normally an opened= inquiry should be made first.
read ( [ unit= ] unit [ , [ fmt= ] format ] , rec= record-number [ , iostat= ios-variable ] ) input-list
write ( [ unit= ] unit [ , [ fmt= ] format ] , rec= record-number [ , iostat= ios-variable ] ) output-list
Other than the addition of the rec= specifier, the read and write statements for direct files
are the same as for sequential files. The record-number is any (default) integer expression,
the value of which specifies the record to be processed.
All of the records of a direct file are the same length (this does not have to be the case for
sequential files). access="direct" and the recl= specifier must be included when opening
direct files; note that the default formatting for direct files is "unformatted", and thus
form="formatted" must also be specified if the direct file is to be formatted. The inquire
statement with the recl= and nextrec= specifiers can be used to, respectively, determine the
record length of a direct file and the record following the last record processed with a
direct file read or write statement.
Note the (syntactic) similarity of nonadvancing I/O with direct I/O, the only differences
being that the format is not optional, and may not be an asterisk, and there is an advance=
specifier rather than a recl= specifier. The "no" can be any scalar (default) character
expression which evaluates to either “no” or “yes” (upper/lower case immaterial); “yes”
represents (the default) ordinary whole-record sequential formatted I/O. An extended
example of nonadvancing read and write statements is:
! read from a file the day-month-year, such as "24 September 1987"; year position unknown;
! write the results in a (slightly) different form to the screen, interleaving the writes with the reads
read (f, fmt="(I2)”, advance="no") day ! assume that i, j, day, year are integer
write (*, fmt="(I3,TR1)”, advance="no") day ! print day to screen, blanks on both sides
do i=1,10
read (f, fmt="(A1)”, advance="no") month(i:i) ! assume that month, m are character
if (i>1.and.month(i:i)==' ') exit ! read characters through second blank
end do ! (first character of month is a blank)
58 Fortran 90 Concise Reference
m = "*** January February March April May June July " // &
“ August September October November December "
j = index(m, month(1:i) )
write(*, fmt="(A3)”, advance="no") m(j+1:j+3) ! now write first three characters of the month
read(f, fmt="(I4)”) year ! (or three asterisks if month "error" in file)
write(*, fmt="(I5)”) year ! finish with advancing read and write for year
! for the above example data the output to the screen is “ 22 Sep 1987”, and no more, on one line
This example illustrates the advance="no" option, of course, but also illustrates that non-
advancing can be used with both file I/O and screen/keyboard I/O. If the interleaving of
the read and write statements had been important then, because of the unknown length of
the Month data, the partial-record I/O is exactly the tool needed. If the interleaving is not
important (which it probably isn’t in the example as shown) then whole-record read and
writes could have been used, together with and internal read (see the next section). Gener-
ally speaking, nonadvancing I/O is indicated when some action must be taken after part of
a record (line) has been input or output and before it is completed.
In nonadvancing I/O the iostat= specifier can be used to detect end-of-record on input as
well as end-of-file. At end-of-file the iostat variable has a negative value and a different
negative value at end-of-record. Unfortunately, these values are implementation depen-
dent, although some implementations provide a module with named constant definitions
that include the end-of-file (typically named EOF) and end-of-record (EOR) values. If the
implementation does not provide such definitions, at least the documentation should iden-
tify what these values are for that implementation; then the programmer can provide the
appropriate named constant definitions. If these values are not readily available then resort
must be made to the end= and eor= specifiers, which specify the branch point label if the
input encounters end-of-file or end-of-record, respectively. The eor= specifier is available
for use only with nonadvancing input.
in which the unit in the read statement is a (default) character expression and the unit in
the write statement is a (default) character variable (R901, R903).
The purpose of an internal write is to convert a set of expression values (the output list) to
a (sequence of) character string(s), just as a formatted write to an external file; the purpose
Input/Output 59
of an internal read is to convert a (sequence of) formatted record(s) - any formatted record
is simply a string of characters - to the proper internal values for a set of variables (the
input list), exactly the role of a formatted read of an external file. Thus internal reads and
writes are exactly the same as external reads and writes, except that the records are inter-
nal character objects rather the same kind of thing in an external file.
An external read “reads from” the record, converts the character values as specified by the
format, and defines the variables in the input list; the record itself is not changed and there-
fore the internal file may in fact be any character expression - it is not limited to a variable.
On the other hand, an external write converts the values in the output list to characters,
according to the format, and “writes” the record; hence the internal file for an internal
write must be a character variable that can be assigned a value. Any character variable, or
element, section, or substring thereof, in an internal file must not appear in the format (if
specified as a character expression) or the input or output list.
Internal files are most often used to convert between numerical values and character string
(and vice versa). A common instance of this is when the format of an record is not known
until after it has been read (into a character string); after determining the format, an inter-
nal read can convert the values to the “target” variables. For example, consider the exam-
ple of the preceding section. A whole-record read, coupled with internal reads, can
accomplish the same thing as the nonadvancing reads:
! read from a file the day-month-year, such as "24 September 1987"; year position unknown;
read (f, fmt="(A)”) iFile ! assume that iFile isa character variable
i = index(iFile, ' '); i = index(iFile(i+1:), ' ') ! assume i, j , day, year are integer
! i is location of the second blank in IFile
read (iFile(:2)), fmt’"(I2)) day ! internal read to convert
month = iFile(3:j) ! assume month, m are character
read (iFile(i:i+4)), fmt’"(I5)) year ! internal read
m = "*** January February March April May June July " // &
“ August September October November December "
j = index(m, trim(month)//' ')
write (*, fmt="(I3,TR1,A3,I5)”) day, m(j+1:j+3), year ! ordinary advancing write to the screen
! output is the same as in preceding section, but all with whole-record and internal I/O
Note in this example that the contents of the entire external record are read into an ordi-
nary character variable (iFile). The index function is then used to identify the substrings on
which internal reads are used to convert the numeric data into the desired variables.
If the internal file cannot be an unallocated array or unassociated pointer; the file for an
internal read must be a valid character expression (that is, all parts must have defined val-
ues). Data transfer in internal file I/O is the same as in external file I/O. Internal file I/O
may be list directed (see next section), but may not be name directed (namelist), direct,
unformatted, or nonadvancing. The file connection (open and close statements), inquiry
(inquire statement), and positioning (backspace, rewind, and endfile) cannot be used with
internal files; the blank="null", delimit="none", and pad="yes" connection specifications are
assumed.
60 Fortran 90 Concise Reference
The format is an asterisk to indicate system-supplied formatting. The unit may be either an
internal or external file, or an asterisk (keyboard/screen); when the unit is an asterisk the
“short form” may be used: read * ... and print * ... .
In list-directed input, the first value is extracted from the record and converted for assign-
ment to the first variable in the input list, the second value extracted, converted, and
assigned to the second variable, and so on until values have been read for all of the input
list variables, or until a slash (/)or end-of-file is encountered. If a slash (or end-of-file) is
encountered and some of the variables have not been assigned new values, those input list
variables retain their current values.
A value in the input file is separated from the next value by a blank or a comma; a comma
may optionally be preceded and/or followed by a blank. (Multiple consecutive blanks in
the input, but not in a character value, are equivalent to a single blank, and blanks are
never zeros.) Consecutive commas (possibly with intervening blanks) represent null input
values, and the corresponding input list variable values are not changed. The end of a
record is treated as a blank.
A numeric input value must be in the form of a numeric constant, assignment compatible
with the input list variable to which it is to be assigned, but binary, octal, and hexadecimal
constants must not be used in list-directed input and the separator characters (blank,
comma, and slash) cannot be part of a logical value (they would be treated as value separa-
tors). A character value may be a character constant, assignment compatible with the cor-
responding input list variable, or not delimited at all; in the last case the first appearance of
a separator character terminates the character value; a separator character appearing in a
character constant is part of the constant, however, and not treated as a separator.
A value may be repeated, much as in the data statement (R532), by preceding it with an
unsigned (default) integer constant followed by an asterisk; for example: 4*1.0 is equiva-
lent to 1.0, 1.0, 1.0, 1.0. Such a repeated construct must contain no blanks (any blank
would serve as a value separator). The repeat without a constant specifies that many con-
secutive nulls; for example 6*, specifies six nulls and is equivalent to , , , , , , , .
Input/Output 61
The format for list-directed output is entirely implementation dependent, except that it
must be (almost) suitable for list-directed input of the same values in the same sequence.
An integer value is in I format, a real value is in F or E format, the real and imaginary parts
of a complex value are enclosed in parentheses and separated by a comma, a logical value
is T or F, and a character value is delimited by the character specified by the delim= speci-
fier in the open statement (note that the delim= default is “none”); if a character value is
written with single (or double) quote delimiters, any single (or double) quote characters in
the character values are repeated once, as per the rules for character constants. The
“almost” in the first sentence of this paragraph refers to the situation where a character
value containing separator characters is written with delim="none"; in this case the list-
directed output does not represent the same set of values for subsequent list-directed input.
A list-directed write statement may output any number of records, and the first character
of each such record is a blank.
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
Name-directed I/O is similar in many respects with list-directed I/O, except that the values
in the input or output list can be in any order. This is accomplished by making two syntax
changes in the read and write statements and keywording the input (and output) values.
The value keywords are modeled after the specifiers (e.g., iostat=...) of the various I/O
statements - the value is preceded by a variable= construct, where variable is the identifica-
tion of the variable to receive that value (input) or whose value is to be written (output);
note that name-directed output works only with variables, not with arbitrary expressions.
The following forms for the name-list read and write statements illustrate the two syntax
changes:
read ( [ unit= ] unit , [ nml= ] group-name [ , iostat= ios-variable ] )
write ( [ unit= ] unit , [ nml= ] group-name [ , iostat= ios-variable ] )
The two changes are: (1) the fmt=* has been replaced by nml=group-name, and (2) there is
no input list or output list, which are also replaced by group-name. The group name is
defined by the namelist specification statement (R543-544), the simplest form of which is:
namelist / group-name / variable-name-list
The namelist statement associates a name (the group name) with a list of variable names;
some or all of these variables, or parts of them, are assigned input values by a name-
directed read statement; similarly the values of some or all of these variables, or parts of
them, are output by a name-directed write statement. Each name in the variable name list
of a namelist statement must be a scalar or array variable name, but cannot be the name of
an array dummy argument with a nonconstant bound, an allocatable array, a variable with
a nonconstant character length, a pointer or an structure containing a pointer, or any other
nondummy argument local variable without the save attribute.
The variable part of a variable=value pair may specify one of the names in the variable name
list, or an element or section of an array having one of those names, a component of a
structure with one of those names, or a substring of a character variable with one of those
62 Fortran 90 Concise Reference
names. The value part of a variable=value pair may be empty (null value), a single scalar
value (if the variable is a scalar), or if the variable is an array (or array section) the value is
either a sequence of comma or blank separated scalar values or of the repeated “*” form
(as in list-directed I/O); as in list-directed I/O, if there is no value following the “*” then
that many null values are specified.
Name-directed input starts with an ampersand followed (immediately) by the group name,
followed by a set of variable=value pairs (in any order), and ending with a slash. Each vari-
able=value must be preceded by a comma or a blank; there may be a blank between the =
and the value. If the variable and value are scalar, that value is assigned to the specified
variable; if the variable is array valued then the specified sequence of scalar values are
assigned to the corresponding elements of the array. Unlike list-directed input, a character
value in name-directed input must be a character constant; otherwise name-directed input
is pretty much the same as list-directed input. Name-directed output has an implementa-
tion-dependent form, but must be (almost) suitable for subsequent name-directed input for
the same variable values; the “almost” is the same as for list-directed I/O - if
delim="none" then character output is not delimited and thus likely would not represent
the same values for namelist input.
Examples of list-directed and name-directed I/O are:
read (labData, fmt=*) name, weight(1:4) ! #1 ! weight is an array
"white rats" 4.3, 5.1, 4.6, 4.3 (input for #1)
namelist / labVars / name, weight ! namelist for #3 and #4, specification part
read (labData, nml=labVars) ! #3 ! same data read as in #1
&labVars weight(1:4)=4.3, 5.1, 4.6, 4.3 name="white-rats" / (input for #3)
Each of the above input statement reads data from a file (labData), and prints it on the
screen. Note that the print * statement may be used for list-directed screen output, but not
for name-directed output. Also note the subtle change in the input data between cases #1
and #3 - in the first case the name is two words separated by blanks, in the second the
blank is replaced with a hyphen; the output for #2 is not suitable for re-input with the #1
read statement, but the #4 output is suitable for re-input with the #3 read statement.
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
As mentioned in the preface, this is an extremely concise version of Fortran’s considerable
I/O sublanguage. It is intended to be complete, however, with nothing left out and no need
to consult other references. Nevertheless the compactness of this description may have
“glossed over” some subtle details which may be better described in either of the refer-
ences given in the preface or some other sources of Fortran 90 information.
Control Structures 63
7 Control Structures
Control structures allow the programmer to (a) select which statements are executed next
(if and select), (b) specify repetitive execution of a group of statements (do), and (c)
branch to another part of the program (goto).
if construct
The if construct has the basic form:
if ( logical-expr ) then
executable-constructs ! the block (R215) “guarded” by logical-expr
end if
If the logical-expr is true then the block of executable constructs is executed; if the logical-
expr is false then the block is skipped. Note that the executable constructs can be any mix
of action statements and other (nested) constructs, such as loops, other if constructs, etc.
The syntax of the if construct is more fully described in syntax rule R802 and the rules it
references.
Another useful form of the if construct is:
if ( logical-expr ) then
executable-constructs ! the block guarded by logical-expr
else
executable-constructs ! the alternative block, if logical-expr is false
end if
In this form the first block of executable constructs (between the if and else), but not the
second (between the else and end if) is executed if the logical-expr is true, and just the
reverse if it is false. This form of the if construct has one logical expression and two blocks
of executable constructs. One can think of the logical expression as “guarding” the first
block; if the “guard” is true the first block is executed and the second one isn’t; if the guard
is false the block it guards (the first one) is not executed and the second one is.
The most general form of the if construct involves n guards (logical expressions) and n+1
blocks of executable constructs (where n can be any integer value greater than zero):
if ( logical-expr ) then ! the first guard,
executable-constructs ! and the block it guards
[ else if ( logical-expr ) then ! any number of additional guards,
executable-constructs ] ... ! and the blocks they guard
[ else
executable-constructs ] ! the alternative block, if all guards are false
end if
Each guard is associated with (guards) “its own” block of executable constructs. The exe-
cutable construct associated with the first guard that is true is executed and the rest of the if
construct is skipped. If none of the guards are true then the unguarded block (the one
between else and end if) is executed. Note that the optionality brackets in the above gen-
64 Fortran 90 Concise Reference
eral form show that the other two forms described above (with just one guard, with and
without an unguarded block) are just special cases of this general form.
An example of an if construct with two guards is:
if ( temperature > BOILING ) then
... ! vapor phase
else if ( temperature > FREEZING ) then
... ! liquid phase
else
... ! solid phase
end if
Finally, Fortran has a single-line if statement, also called the logical if:
if ( logical-expr ) action-stmt ! see R216 for definition of action-stmt
In this case the action statement is executed if (and only if) the logical expression is true.
The logical if is especially handy when you want to get out fast:
if ( code == "DONE" ) exit ! exit loop when processing is finished
The guards in an if construct need not be disjoint - that is any of them can be true at the
same time. But only one block of executable constructs is executed - that one guarded by
the first (top most) guard that is true. In the case (select) construct, however, at most one
guard can be true at any given time.
case construct
The case construct also involves n guards and n+1 blocks of executable constructs, only
one (or, more precisely, at most one) of which is executed. The order of the guards in a
case construct is immaterial (whereas the order of the guards in an if construct may well
be critical - witness the temperature example above).
The case construct syntax is described in detail in R808 and the syntax rules it references.
The general form is:
select case ( case-expr ) ! the case expression to be evaluated;
[ case ( case-value-list ) ! if the case-expr value matches one of these
executable-constructs ] ... ! then this block is executed;
[ case default ! if no match exists
executable-constructs ] ! then this block is executed;
end select
The case expression and case values may be of type integer, type character, or type logical;
all of the case values are constants, and all of the case-value lists are disjoint. The block of
executable constructs corresponding to (guarded by) the case-value list that contains the
value of the case expression (or the default block, if there is one and there is no value
Control Structures 65
match) is the block executed. Since the case-value lists are disjoint, the case expression
value can match at most one, and therefore the order of the case blocks, including case
default, is immaterial.
do construct
Modern loop constructs do not involve statement labels. For compatibility with older For-
tran code, which makes extensive use of the original labelled form of the do construct,
Fortran 90 has three categories of do construct:
(a) a modern construct (do - end do) without any labels
(b) the modern construct with labels
(c) the original style
Category (b) is the same as (a) with an optional label, and is provided for those who want
the modern structure but prefer to have loops with labels.
The syntax of all forms of the do construct is described in R816 and the syntax rules it ref-
erences. The modern form, without labels (category (a)), itself comes in three flavors -
infinite, indexed, and while:
do ! the “infinite” form -
executable-constructs ! looping stops only by explicit exit
end do ! from within the loop body
do while ( logical-expr )
executable-constructs ! the while form
end do
66 Fortran 90 Concise Reference
Execution of the infinite do construct “loops forever” unless there is an exit statement
somewhere in the block of executable constructs (loop body).
The semantics of the indexed do is best described by making the first line more specific:
do i = e1, e2, e3
Then the semantics of the indexed do are equivalent to:
i = e1-e3
do; i = i+e3; if ( i > e2 ) exit
executable-constructs
end do
If e3 is omitted, a value of +1 is assumed; if e3 is negative then the test is i < e2 rather than
i > e2. Of course a value of zero must not be specified for e3. (See R817 and related syntax
rules for additional, but inconsequential, syntax details of the indexed do construct.)
The semantics of the while loop are:
do; if ( .not. logical-expr ) exit ! in the while loop the test is
executable-constructs ! made at the top of the loop
end do
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
The modern form with labels (category (b)) simply replaces do and end do with labelled
versions of these statements (same label on both); the label is described in R313; the unla-
beled and labelled versions of these two statements are summarized as follows:
unlabeled labelled
do do label
end do label end do
label continue
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
The original style DO-loop (category (c)) required labels and did not have end do. Though
it allowed terminating a loop on a labelled continue statement, it did not require it; the
(labelled) last statement could be the final action statement of the loop body (R827). (Note
that such an action statement could not, however, be a goto, return, or other branching
statement.) Moreover, two (or more) nested loops could share the same termination state-
ment (and label) - see R830. For example, a two-dimensional array can be initialized with
the nested loops:
do 101, i=1,m
do 101, j=1,n
101 x(i,j) = 0
do i=1,m
do i=1,m
x(i,j) = 0
end do
end do
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
The execution of any loop may be explicitly and immediately terminated (with an exit
statement, R835) or advanced to the next iteration (with a cycle statement, R834) any-
where within the loop body. The most common use of these features is to exit a loop upon
the occurrence of some condition. A common pattern, for example, is the read-test-process
nature of processing file data:
do
... ! read the next record
if ( end-of-file ) exit ! test to see if at end of file
... ! process the data just read
end do
If only part of the records are to be processed, then the loop could be:
do
... ! read the next record
if ( end-of-file ) exit ! test to see if at end of file
if ( not-of-interest ) cycle ! record not of interest, so go on to next
... ! process the data just read
end do
In the nested loop case these simple forms of exit and cycle apply only to the inner-most
loop in which they appear. To make them apply to an outer loop, that outer loop must be
named with a construct name (R818, R825) and the exit (or cycle) statement must specify
this name. For example:
outer_loop: do
...
do
...
if ( . . . ) cycle outer_loop
...
end do
...
end do outer_loop
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
goto statements
The if, case, and do constructs provide the disciplined, readable, and reliable way to con-
trol the execution sequence. The goto statement, and variations, are primitive, but power-
ful, branching statements that allow execution to be switched to (almost) any other place
in the current scope. The basic goto (which can also be spelled go to) has the form:
goto label ! see R836
68 Fortran 90 Concise Reference
Execution of a goto statement causes execution to resume with the statement having the
label specified in the goto statement. Any action statement may be labelled, as well as the
if, select, or do statement (that is, first statement) of a control construct.
A goto statement must not cause a branch into the body of an if, select, or do construct
from outside that construct, but the reverse (branch out from inside) is allowed.
Though a label may be placed on any action statement, plus a few others, many program-
mers prefer to use only the continue statement to identify a branch point:
label continue ! see R840; execution of continue “does nothing”
The computed-goto statement (deprecated - see chapter 5) specifies a list of labels and
causes a branch to one of them, depending on the value of an integer expression:
goto ( label-list ) int-expr ! see R837
For example:
goto ( 222, 333, 222 ) K/5 ! assume K is an integer variable
causes a branch to the statement labelled 222 if K is in the 5-9 range or 15-19 range, to the
statement labelled 333 if K is in the10-14 range, and has no effect otherwise.
The assigned-goto statement (also deprecated) uses an integer variable as a label:
goto int-variable [ ( label-list ) ] ! see R839
Prior to executing an assigned-goto statement, the integer variable must have been
assigned a label value with the assign-statement (also deprecated):
assign label to int-variable ! see R838
If the optional label-list is included in the assigned-goto statement, the label value of the
integer variable must match one in the list.
The arithmetic-if (also deprecated) causes a branch to a specified label, based upon a
numeric value:
if ( numeric-expr ) label , label , label ! see R840
If the numeric value is less than zero the branch is to the first label, if the value is zero the
branch is to the second label, and if the value is greater than zero the branch is to the third
label.
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
The stop statement (R842-843) is a special kind of a branch - it terminates execution of
the program; it can be placed in any execution sequence and, as an above example indi-
cates, can be used to “get out quick” when disaster strikes. In normal use it is redundant,
however, as the end statement of the main program serves to terminate execution of the
program. Note that in those exceptional cases where it is useful, the stop statement can
issue a relevant message, which on most systems is printed on the screen at termination.
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
Modules 69
8 Modules
The module is a new program unit in Fortran 90 that provides definitions for use in other
program units; modules may be placed in separate files and re-used with different pro-
grams.
A module is not executable; it contains definitions to be used by other program units; these
definitions include procedures, which are individually executable, but the module itself is
not executable.
Module entities are made available to other program units by the use statement:
program Seismic_Processing
use Seismic_Trace_Definitions
...
end program
Available modules entities are said to be “use associated” within the using program. A
module may contain private entities; such entities are not available to using program units
(private entities are available only within the module itself, including any procedure defi-
nitions within the module). In addition, the only form of the use statement limits the mod-
ule entities that are available in the using program unit.
The principal contents of a module include: type definitions, interface definitions, proce-
dure definitions, and shared data objects (including global constants). Typical uses of
modules include: procedure libraries (with explicit interfaces), encapsulated data abstrac-
tions, and shared-data units (alternative to COMMON).
module structure
The general structure of a module (R1104-1106) is as follows; additional syntax rules are
listed for specific items in the following description:
module module-name
use-statements ! modules can (optionally) use (import) other modules
constant-definitions ! global constants - see R538 and the parameter attribute
variable-declarations ! shared variables - see R501
interface-blocks ! explicit interfaces, defined operators, overloading - see R1201
type-definitions ! user-defined data types - see R422
contains
module-subprograms ! see R213
end module
module use
Other program units (main programs, functions, subroutines, and other modules) may use
the definitions provided in a module by including a use statement (R1107-1109) immedi-
ately after the program unit heading, as in the Seismic_Processing example above:
70 Fortran 90 Concise Reference
use module-name, only: only-list ! imports only the specified public entities
Module entities are imported into the using program with the same name as they have in
the module, unless they are renamed in the use statement; this may be necessary to avoid
name conflicts, as an imported (“use associated”) name does not “mask” a local entity
with the same name. A rename (R1108) has the form:
local-name => use-name
where local-name is the new name (in the using program) and use-name is the name of the
entity in the module (the new name “points to” the module entity). An only (R1109) can be
either the name of the module entity being imported, or a rename:
[ local-name => ] use-name ! renaming is optional in an only-list
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
A module for the above Seismic_Processing program might take the form:
module Seismic_Trace_Definitions
real, parameter :: PI=3.1415926 ! a global constant
real, allocatable :: seismicWorkArray(:,:) ! a shared data work-space
contains
!-----------------------------------------
function FFT (...) ! definition of function FFT
...
end function FFT
!-----------------------------------------
subroutine FFT_C (...) ! subroutine FFT_C can also be called
... ! with the name FFT, because of the
end subroutine ! overload defined above
!-----------------------------------------
subroutine timeDomain (...) ! another procedure definition in this module
...
end subroutine
!-----------------------------------------
end module
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
Modules 71
module applications
A module might contain just shared (global) constants and variables:
module Shared_Data
real, parameter :: PI=3.1415926 ! a shared (global) constant
integer :: n_rho, n_vel ! two shared variables
real, allocatable :: workArray(:,:) ! a shared array
end module
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
A module might comprise a procedure library:
module Procedure_Library
contains
!-----------------------------------------
function FFT (...)
...
end function FFT
!-----------------------------------------
subroutine timeDomain (...)
...
end subroutine
!-----------------------------------------
...
!-----------------------------------------
end module
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
A module might be used to collect a set of procedure interfaces, for use by other program
units; these can include (1) explicit interfaces for external procedures, (2) generic (over-
loaded) names for specific procedures, and (3) operator symbol definitions:
module Procedure_Interfaces
!-----------------------------------------
interface ! providing an explicit interface
subroutine T_time (A) ! for external procedure T_time
real :: A(200,300)
end subroutine T_time
end interface
!-----------------------------------------
interface FFT ! overloading FFT for use with FFT_C and FTT_R
subroutine FFT_C (...)
... ! FTT_C is defined external to this module
end subroutine
module procedure FFT_R ! and FTT_R is defined in this module
end interface
!-----------------------------------------
72 Fortran 90 Concise Reference
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
A module might contain definitions of user-defined types (or record structures):
module Derived_types
!-----------------------------------------
type Point ! a type to similate a 3D point in two ways
real :: x_r
real :: y_rho
real :: z_theta
logical :: cartesian
end type
!-----------------------------------------
type List ! a typical linked list structure node
type (Point) :: data
type (List), pointer :: next
type (List), pointer :: prev
end type
!-----------------------------------------
type Seismic_trace; private ! a new type with “hidden” internal structure
character(20) :: trace_ID
real, pointer :: traceData(:)
end type
!-----------------------------------------
end module
Modules 73
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
A module might encapsulate a complete data abstraction:
module Interval_Arithmetic ! a data abstraction for interval arithmetic
!-----------------------------------------
type Interval; private ! the basic data structure is private; an interval
real :: lower, upper ! is represented by its upper and lower bounds
end type
!-----------------------------------------
interface operator(+) ! use “+” for adding intervals
module procedure interval_plus_interval, &
interval_plus_real, &
real_plus_interval
end interface
!-----------------------------------------
interface operator (*) ! use “*” for multiplying intervals
module procedure interval_times_interval, &
interval_times_real, &
real_times_interval
end interface
!-----------------------------------------
interface sqrt ! extend “sqrt” to interval arguments
module procedure interval_sqrt
end interface
!-----------------------------------------
... ! other interfaces ....
!-----------------------------------------
contains
!-----------------------------------------
function interval_plus_interval (a, b) ! one of the addition functions
type (Interval) :: interval_plus_interval
type (Interval), intent(in) :: a, b
...
end function
!-----------------------------------------
function interval_plus_real (a, b) ! another addition function
type (Interval) :: interval_plus_real
type (Interval), intent(in) :: a
real, intent(in) :: b
...
end function interval_plus_real
!-----------------------------------------
function real_times_interval (a. b) ! etc....
type (Interval) :: real_times_interval
real, intent(in) :: a
type (Interval), intent(in) :: b
...
end function
!-----------------------------------------
74 Fortran 90 Concise Reference
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
Procedures 75
9 Procedures
Subroutines and functions are the two forms for Fortran 90 procedures; each may appear
in the following contexts: external (stand-alone, separately compiled), module (packaged
within a module definition), internal (packaged within another procedure or main program
definition). Fortran 90 has a large number of built-in intrinsic procedures; these are sum-
marized here and described in detail in chapter 10. Both subroutines and functions are
used to encapsulate particular computations, and the principal difference between them is
the manner in which they are used (called, invoked). A subroutine does not return a value
(except possibly through its argument list) and is invoked by a separate subroutine call
statement; a function returns a value and is invoked by using its name (and arguments) in
an expression in which its returned value is used.
Procedures interact with each other (primarily) through argument lists, and these inter-
faces are either explicit (known) or implicit (unknown) to the calling procedure; only
external procedures have implicit interfaces; interface blocks can make even these inter-
faces explicit. Procedures can be generic (multiple procedures called by the same name),
and procedures may be used to define new operators.
subroutines
A subroutine is defined by a subroutine subprogram (R1219), which has the form
subroutine subroutine-name ( dummy-arg-list )! see R1221 for dummy arguments
specification-part ! see R204 for specification-part
execution-part ! see R208 for execution-part
internal-subprogram-part ! see R210 for internal-subprogram-part
end subroutine
Any of the three parts in a subroutine definition may be empty, but a subroutine will nor-
mally have a specification part (e.g., argument declarations) and do some computation
(execution part). If the subroutine is recursive, it definition starts with the keywords recur-
sive subroutine rather than just the keyword subroutine. See R1219 for some minor syntax
options (such as allowing the subroutine name to be repeated on the end subroutine state-
ment).
A subroutine definition may be placed in:
(1) the internal-subprogram-part of a module (R1104), in which case it is a module sub-
routine,
(2) the internal-subprogram-part (R210) of an external subroutine definition, an external
function definition, a main-program (R1101), or a module procedure definition, in
which case it is an internal subroutine,
(3) its own file, or a file with other stand-alone procedure definitions, in which case it
is an external subroutine.
76 Fortran 90 Concise Reference
An external subroutine has an implicit procedure interface (if no interface block is sup-
plied for it) and, as it has no host, does not access a host data environment. (An external
subroutine is also the only kind of subroutine in which end is an acceptable abbreviation
of the end subroutine statement.)
A module subroutine has an explicit interface and accesses the data environment of its
host module; an internal subroutine has an explicit interface and accesses the data environ-
ment of its host procedure.
In all cases, a subroutine is invoked with a call statement (R1210):
call subroutine-name ( actual-arg-list ) ! see R1213 for actual arguments
If the subroutine’s interface is explicit the compiler can enforce consistency between the
actual-arg-list in the call statement and the dummy-arg-list in the subroutine definition;
otherwise interface consistency is not enforceable. (Interface inconsistency is the source of
difficult-to-find errors in programs with implicit interfaces.)
(Note: subroutine argument lists may include alternate returns (deprecated - see chapter
5), and this is the only way that subroutine argument lists differ from function argument
lists. An alternate return is an asterisk (*) in a dummy-arg-list; the corresponding actual argu-
ment must be a *label (e.g., *220) specifying the alternate return point.)
functions
A function is defined by a function subprogram (R1215), which has a form similar to that
of subroutines:
[ type-spec ] function function-name ( dummy-arg-name-list ) [ result ( result-name ) ]
specification-part ! same
execution-part ! as in
internal-subprogram-part ! subroutines
end function
As with a subroutine, recursive must be added to a recursive function (R1217), and the
result clause is required for recursive functions (and optional for all other functions). See
R1215 for other (minor) syntax options. Functions may be internal, module, or external in
exactly the same way as subroutines, with the same implications in each case.
Each function returns a result value and therefore must have a result type; that type may be
specified on the function statement (type-spec) or in the specification part of the function.
Function results may be of any type, including derived type, and may be array valued; if
the function is array valued, the array (dimension) attributes must be specified in the spec-
ification part. The result clause, if present, specifies the name to which the result is
assigned in the execution part; otherwise the function name is also the result name.
A function is invoked as an operand in an expression, not as a stand-alone statement, and
its result value becomes the value of that operand; such a function call has the form
(R1209):
Procedures 77
function-name ( actual-arg-list )
Explicit interfaces and arguments work the same for functions as for subroutines, except
that alternate returns are not allowed in function arguments lists. The result clause is
required for recursive functions for the following reason. Consider:
recursive function rf(a,b) result(rf_result)
integer :: a, b
real :: rf_result(2,3)
...
... = rf(2,1)
...
end function rf
If the result clause had not been present, then rf would be used for the result value as well
as for recursive calls. Because rf has two integer arguments and returns a two-dimensional
array, the reference rf(2,1) could be either a recursive call or a reference to an element of
the result. Though only very few combinations of argument lists and arrayness cause such
ambiguity, nevertheless the Fortran 90 rule is “recursive implies result”.
host association
All procedures have the following four data access mechanisms: (1) local entities, (2)
argument association, (3) use association, and (4) common association. The second of
these (argument association) allows a procedure to access entities explicitly “passed” by
the procedure’s caller; the third (use association) refers to module entities accessed via use
statements in the procedure’s specification part; the fourth (common association) refers to
entities in the common blocks listed in the specification part. These are the only data
access mechanisms for external procedures.
Module procedure and internal procedures have a fifth mechanism - host association. Host
association refers to a procedure’s access to entities declared in the procedure’s host. The
host of a module procedure is the module that contains its definition; the host of an inter-
nal procedure is the procedure (or main program) that contains its definition. Any entity
declared in the host is automatically accessible by that declared name in the contained pro-
cedure - even private module entities (private affects only use association) - unless the con-
tained procedure has an explicit declaration of that name. In the latter case the name refers
to an entity local to the procedure and not to the host entity with this name; the host entity
is then available to the procedure only through argument association. The following exam-
ple illustrates these concepts:
program P
integer :: x
real :: y
...
call s1(x) ! x is passed to the procedure s1
...
contains
78 Fortran 90 Concise Reference
In the execution part of subroutine s1, x is (always) the local real variable (not the host’s
integer x), y is (always) the host’s real variable, and z is the argument-associated entity; in
the shown call to s1, z becomes associated with the host’s x, and thus for this call z in the
procedure’s execution part refers to the host’s x.
In the preceding example the host-association rules are simple and “obvious” because all
entities are explicitly declared. Fortran 90 allows implicit declaration of variables, how-
ever, which can make host association less obvious. The above rules, as stated, still apply;
the one missing piece is this: a variable implicitly declared in the host is host associated as
if it were explicitly declared and a variable implicitly declared in a contained procedure
(possible only if it has not been explicitly or implicitly declared in the host) is local to the
procedure. Recall that a variable is implicitly declared if there is no type declaration for its
name in the specification part, but its name is referenced in the execution part. The follow-
ing example illustrates the host-association rules involving implicit declarations:
program P ! no type declarations in the host
...
call s2(x) ! x implicitly declared in the host
...
contains
subroutine s2(z) ! no type declarations in s2
...
print *, x, y, z ! x is host associated
... ! y is local to s2
end subroutine ! z is argument associated (with x in this case)
end program
In this example subroutine s2 accesses three variables, x, y, and z, all implicitly declared. x
is implicitly declared in the host, by virtue of its reference in the call statement, and thus is
host associated in s2. y is not (explicitly or implicitly) declared in the host and so is
implicitly declared in s2, by virtue of its reference in s2, and is therefore local to s2. z is
argument associated.
The default implicit typing rules in a main program, module, or external procedure are: all
default real except variables starting with letters I-N, which are implicitly default integer.
Implicit typing can be turned off (with implicit none, which then requires that all variables
to be explicitly typed) or modified by implicit statements (R540) in the specification part of
the host. Whatever implicit typing is in effect in the host becomes the default implicit typ-
ing in the contained procedure. This can in turn be turned off (implicit none) or modified
by implicit statements in the specification part of the contained procedure. These are
straightforward, consistent rules, but by far the simplest host association scenario is
explicit declaration of all entities in both the host and the contained procedures.
Procedures 79
Note that actual arguments that are substrings work well with assumed-length dummy
arguments. Similarly, actual arguments that are array sections work well with assumed-
shape dummy arguments.
This simple set of argument association rules is all that is needed, and is the preferred way,
to develop new Fortran code and to update existing code. However, assumed-shape
dummy arguments require explicit procedure interfaces, and much existing code predates
Fortran 90, explicit interfaces, and assumed-shape dummy arguments. Fortran 90 allows
the array element sequence association mechanism for array arguments that Fortran pro-
vided prior to Fortran 90. In this case the dummy argument is declared as either an
explicit-shape array (R513) or an assumed-size array (R518); the principal difference
between the two is that the last dimension of an assumed-size array is declared as an aster-
isk. An actual argument array must have a size (total number of elements) at least as big as
an associated explicit-shape or assumed-size dummy array (a condition that will automati-
cally be satisfied by an assumed-size array).
Array element sequence association treats the associated actual and dummy arrays each as
a linear sequence of array elements, with the corresponding elements of each sequence
being associated; thus the nth element of the actual array sequence is associated with the
nth element of the dummy array sequence. The order of such a sequence is Fortran’s array
80 Fortran 90 Concise Reference
element order, which varies the first subscript first, the second subscript next, and so on.
Thus, for a two-dimensional array, array element order is the first column followed by the
second column, and so on; for the array declared as real :: x(3,2), array element order is
x(1,1), x(2,1), x(3,1), x(1,2), x(2,2), x(3,2).
Array element sequence association means, essentially, that the ranks of the actual and
dummy arguments are immaterial, and therefore the ranks are not required to match in this
form of argument association. If the actual argument is an array section (and the dummy
argument is not assumed shape) the processor must generate an array element sequence
for array element sequence association with the dummy argument; this may involve copy-
ing the array section into a contiguous area of memory before association with the dummy
array, and then refreshing the original array section from this copy after execution of the
procedure call is completed (copy-in, copy-out).
If character arrays are involved in array element sequence association there is one addi-
tional wrinkle - the sequences generated are character sequences, not array element
sequences, and the association is character by corresponding character. If the character
length of the actual and dummy array elements are the same (as they would be with
assumed length) then this character association is equivalent to array element association.
With array element sequence association both the array rank and character length can be
“changed” across procedure boundaries, with the indicated consequences for argument
association.
Array element sequence association is permitted in any procedure, by declaring the
dummy array as an explicit-shape or assumed-size array, and is the only option for proce-
dures with implicit interfaces - that is external procedures without interface blocks. In
those cases where the interface is explicit (all module and internal procedures, and exter-
nal procedures with interface blocks) both array element sequence association and
assumed-shape array association are permitted (and normally assumed-shape array associ-
ation is preferred).
Structure (derived type) argument association follows the same rules as for other types -
namely, the actual and dummy arguments must be the same type. This means they must be
derived from the same type definition. Another form of structure association, called struc-
ture sequence association, involves sequence structures (R422-423). In this case the “same
type” rule for the actual and dummy arguments is relaxed in favor of equivalent types.
Equivalent structure types are sequence types with the same type name and with compo-
nents that are all public and agree in order, name, and type (or equivalent type).
A caveat about procedure arguments, regardless of the association mechanism, is that if
the same entity becomes associated with two (or more) dummy arguments then, in order to
prevent nondeterminism in results, the procedure must treat both dummy arguments as
intent(in). There are two common instances of this situation. One is when an actual argu-
ment is an array section with at least one vector subscript; in this case two or more of the
actual array elements may be the same element of the section’s parent array and will be
associated with different dummy array elements. The second case is when the same data
entity is used two (or more) times in an actual argument list: e.g., call s3(x,y,x).
Procedures 81
For procedures with explicit interfaces, the actual argument list may be keyworded
(R1211-1212). When the interface is explicit, the dummy argument names are known to
the procedure’s caller. This information allows the actual arguments to be placed in any
order, if the dummy argument names are used as argument keywords in the call. For exam-
ple, in this call to subroutine s4 (which has dummy arguments d1, d2, and d3, in that order)
call s4(d2=x, d3=y, d1=z)
the actual arguments are not in the order of their associated dummy arguments, but
because the interface is explicit the processor can create the intended associations.
A dummy argument may be declared as optional (R503, R520). This effectively creates
overloaded (generic) versions of the procedure, and calls to such procedures are resolved
in accordance with the generic reference resolution rules (see below). The present intrinsic
function is available for use within the procedure to determine if in a given call to the pro-
cedure the optional dummy argument has an associated actual argument or not. Note that
either optional arguments must be the last ones in the dummy argument list or calls that
omit actual arguments must be keyworded. In any event, optional arguments require
explicit interfaces.
Dummy arguments are references to (aliases for) their associated actual arguments. One
consequence of this is that any change to a dummy argument is reflected in the actual
argument. The intent may be specified for a dummy argument to control such “unbridled”
access in some respects. The intent attribute (R503, R511, R519) may limit the use of the
dummy argument to in, out, or inout. Intent(in) arguments are intended for input to the
procedure; the actual argument must be defined upon entrance to the procedure - it may be
a variable or an expression - and the dummy argument must not be defined in the proce-
dure. Intent(out) arguments are intended for procedure output - the dummy argument must
be defined at some point during execution of the procedure (thus the actual argument must
be a variable); the associated actual argument need not be defined upon entrance, so an
intent(out) dummy argument must not be referenced in the procedure before it is defined.
Intent(inout) specifies that the actual argument must be defined upon entrance and the
dummy argument may be defined in the procedure; the associated actual argument must be
a variable.
Procedures may be passed through argument lists. That is, a dummy argument may be
declared as a procedure name (in an external statement, intrinsic statement, or in an inter-
face block) or used as a procedure name (in a call statement or in a function reference).
The associated actual argument must be the name (without an argument list) of a specific
procedure (generic procedures cannot be passed). If the dummy argument is declared or
used as a function name, the associated actual argument must be the name of a function; if
the dummy argument is declared or used as a subroutine name, the actual argument must
be the name of a subroutine. Except for internal procedures and statement functions,
which cannot be used as actual arguments, any specific procedure, including any specific
intrinsic function, may be used as an actual argument.
82 Fortran 90 Concise Reference
interface blocks
A procedure interface comprises the information needed to use that procedure correctly;
explicit interfaces make this information available to the calling environment. Interface
blocks are used to provide various explicit interfaces. Explicit interfaces include dummy
argument list characteristics, alternate names for a procedure (primarily used to define
procedure overloads - that is, generic procedures), and new operator and assignment defi-
nitions.
Interface blocks are not needed to make module and internal procedure interfaces explicit,
as these interfaces are automatically explicit wherever such procedures are accessible.
However, external procedure interfaces are not automatically explicit; interface blocks
(R1201) with one or more interface bodies (R1204) may be used to make them explicit:
interface
interface-body
[ interface-body ] ...
end interface
Each interface body specifies an external (or dummy) procedure name, its type (if it is a
function), and the order names, and types (and kinds) of all dummy arguments.
If a function has certain properties it may be given an operator interface, thereby creating
a defined operator, and called using operator notation; it must have one (unary operator) or
two (binary operator) intent(in) arguments. Such a function may be called with either the
normal function syntax or infix operation format; in the latter form the first actual argu-
ment appears as the first operation operand and the second actual argument is the second
operand (for unary operators the operand follows the operator). The operator form of the
interface block is used to define a new operator and associate it with one (or more) func-
tions:
interface operator ( defined-operator ) ! suppose this defines an overload of “+”; then
[ interface-body ] ... ! sum_char_int(c,i) the function form
[ module-procedure-stmt ] ... !c+i the operator form
end interface
A defined operator can be either a user-defined dot operator or (an overload of) an intrinsic
operator (R311), as in the preceding example. If it is an intrinsic operator it must not rede-
fine an intrinsic operation - for example, the + operator must not be given an operator
interface for a function with two integer arguments, as that would be an attempt to redefine
addition of two integer values. All operator definitions are considered to be generic proce-
Procedures 83
dure definitions and must be consistent with the generic reference resolution rules (see
below). The function(s) associated with a defined operator may be either external func-
tions (in which case the interface contains the corresponding interface bodies, as in the
above example) or accessible module functions (in which case the interface contains the
corresponding module procedure statements).
If a subroutine has two arguments, the first being intent(out) or intent(inout) and the sec-
ond being intent(in), then it may be given an assignment overload:
interface assignment ( = )
[ interface-body ]...
[ module-procedure-stmt ]...
end interface
An example is:
interface assignment ( = )
subroutine to_char_from_int(c, i) ! if code is a character variable and n is integer
character :: c ! to_char_from_int can be called in two ways:
integer :: i ! call to_char_from_int(code,n)subroutine form
end subroutine ! code = n assignment form
end interface
The purpose of such a subroutine is to convert the value of the second argument to an
appropriate value for the type of the first argument, and to assign this converted value to
the first actual argument; the subroutine defines the conversion that takes place in such an
assignment. The assignment interface makes it possible to use assignment syntax for this
operation, as an alternative to using normal subroutine calls. In analogy with operator
interfaces, assignment interfaces define assignment overloads and thus must be consistent
with the generic reference resolution rules. Intrinsic assignments cannot be redefined
except for intrinsic assignment of structures (that is, derived type intrinsic assignment). As
with operator functions, assignment subroutines may be either external subroutines or
module subroutines.
Interface blocks may be used to define overloaded (generic) procedure names. Any proce-
dure name may be (further) overloaded, including an intrinsic procedure name:
interface generic-name
[ interface-body ] ...
[ module-procedure-stmt ] ...
end interface
A generic name may be associated with any number of external procedures and module
procedures. Such a procedure may be called using either its original (specific) name or the
generic name. A call to a procedure using the generic name is considered to be a generic
reference; any generic reference must be resolvable to a specific procedure, in accordance
with the generic reference resolution rules. Generally speaking, this means that each pro-
cedure sharing the same generic name must have a different argument “signature” (type
pattern). External and module procedures may be given generic interfaces.
84 Fortran 90 Concise Reference
generic procedures
A generic procedure is one that can be called in more than one way. These include proce-
dures with generic as well as specific names, functions with operator interfaces (function
reference and operator form), and subroutines with assignment interfaces (subroutine call
and assignment syntax). The only restriction on the proliferation of generic procedures is
that each reference be resolvable to the appropriate underlying specific procedure.
There are two rules which allow generic procedure references to be resolved to a unique
specific procedure. the first of these rules (rule (a) below) derives from the positional sig-
nificance of an argument when keyworded calls are not involved; the second (rule (b))
imposes a further restriction in order to disambiguate keyworded calls. If two procedures
may be called with the same generic name (or with the same operator or assignment syn-
tax), one of the argument lists must have a nonoptional dummy argument that (a) has a
type/kind/rank pattern different from that of the dummy argument (if one) in the same posi-
tion in the other argument list and (b) has a name/type/kind/rank pattern different from
that of all the dummy arguments in the other argument list. That is, there must be at least
one argument that disambiguates two generic references on the basis of it type/kind/rank
signature (and dummy argument name also, in the case of keyworded calls).
Most of Fortran’s intrinsic procedures are generic, and references to these intrinsics are
resolved in the same manner as described above. Intrinsic functions have an additional
generic form: many of them are elemental. An elemental function is one defined with a
scalar dummy argument and a scalar result. It may, however, be called with an array actual
argument, and in this case delivers an array result with the same shape; the value of each
result element is the same as if the function had been called with the corresponding actual
argument array element.
return statement
The return statement (R1224) is a separate statement that causes return from a procedure,
in the same way as the procedure’s end statement. return can be used anywhere in the exe-
cution part, but is needed only in exceptional cases. See chapter 5 for alternate returns.
statement functions
A statement function is a “one-liner” function (R207, R1226), with scalar arguments and a
scalar result, for use only in the program unit in which it is defined. Statement functions
are not internal procedures, their interfaces are always implicit, they may not be used as
actual arguments, and they employ only intrinsic operations. Statement function calls have
the normal function call syntax and argument association rules. (See also chapter 5.)
entry statements
The entry statement (R1223) can be used to provide alternate entry points into a proce-
dure; the entry statement has a name and an argument list, similar to the function or sub-
routine statement, and can be placed anywhere in a function or subroutine definition. The
original purpose of the entry statement was for data -sharing among different procedures,
a functionality now better provided by internal and module procedures.
Procedures 85
intrinsic procedures
The rest of this chapter is devoted to summarizing and categorizing Fortran 90’s 113
intrinsic procedures (108 intrinsic functions and 5 intrinsic subroutines). This summary
has nine categories of procedure, each with certain similar characteristics, and ends with a
concise alphabetical listing of all 113 intrinsic procedures and their arguments. Each
intrinsic procedure is described more fully, in alphabetical order, in the next chapter.
numeric inquiry functions
digits significant digits (e.g., bits) for a given integer or real kind
epsilon a small value (small compared to 1) for a given real kind
exponent the exponent value for a given real value
fraction the fractional part of a given real value
huge the largest value representable for a given real or integer kind
minexponent the minimum exponent value for a given real kind
maxexponent the maximum exponent value for a given real kind
nearest the processor value nearest to a given real value, in a given direction
precision the decimal precision of a given real or complex kind
radix numeric base (typically binary) for a given real or integer kind
rrspacing reciprocal of the relative spacing near a given real value
range the decimal exponent range of a given numeric kind
scale change the exponent of a given real value by a specified amount
set_exponent set the exponent of a given real value to the specified amount
spacing the absolute spacing near a given real value
tiny the smallest positive value representable for a given real kind
conversion functions
achar the character in the specified position of the ASCII character set
aimag the imaginary part of a given complex value
aint a given real value truncated to an integer (result is still real)
86 Fortran 90 Concise Reference
anint a given real value rounded to the nearest integer (result is still real)
char the character in the specified position of the processor character set
cmplx the complex value of a given single or pair of integer or real values
conjg the complex conjugate of a given complex value
dble the double precision value of a given numeric value of any type
iachar position of the specified character in the ASCII character set
ibits the specified substring of bits of a given integer value
ichar position of the specified character in the processor character set
int the (truncated) integer value of a given numeric value of any type
logical the logical value of specified kind for a given logical value
nint the (rounded) integer value of a given real value
real the real value of a given numeric value of any type and kind
transfer conversion to a specified type without change in the “bit pattern”
len_trim length of a given string after trailing blanks have been removed
lge greater than or equal to ASCII comparison of two given strings
lgt greater than ASCII comparison of two given string values
lle less than or equal to ASCII comparison of two given string values
llt less than ASCII comparison of two given string values
repeat concatenate several copies of a given string value
scan search a given string value for any of a given set of characters
trim remove trailing blank characters from a given string value
verify position of a character in a string that is not one of a given set
intrinsic subroutines
date_and_time returns date and time information in several formats
mvbits copies a sequence of bits between given integer values
random_number returns one or more pseudorandom numbers
random_seed allows setting of the random number generator seed value
system_clock returns various data from the processor’s real-time clock
88 Fortran 90 Concise Reference
dble (a)
digits (x)
dim (x, y) dim (x,y) default real
idim (x,y) default integer
dot_product (vector_a, vector_b)
dprod (x, y)
eoshift (array, shift, boundary, dim) boundary,
dim
epsilon (x)
exp (x)
Procedures 89
10 Intrinsic Procedures
The 113 intrinsic procedures are introduced and organized in the previous chapter, and each is
described in detail in this chapter. A “pseudo” interface block, without the interface ... end interface
bracketing keywords, describes the interface of each procedure; the semantics is described in com-
ments in the interface, often augmented by text following the interface. Constraints and other rele-
vant information are also included, either in the interface comments or in the following text.
Most of the intrinsic procedures are generic over the various kinds of the argument type - for exam-
ple, sqrt is generic for both single and double precision real arguments, and any other real kinds the
implementation might supply. Unless explicitly mentioned otherwise, each single-argument intrin-
sic procedure is generic in this sense, with the result kind being the same as the argument kind.
Similarly, each intrinsic function with one argument plus a kind argument is generic in this sense,
but with the result kind as specified by the kind argument.
As described in the previous chapter, intrinsic procedures may be classified as either elemental or
transformational (most are elemental). If an intrinsic procedure is elemental the interface starts
with the keyword elemental; otherwise that procedure is tranformational. (In a call to an elemental
function with two or more arguments, the actual arguments must be conformable; but note that a
scalar is conformable with any array.) Similarly, some intrinsic functions are identified as inquiry
functions with the keyword inquiry; actual arguments to inquiry functions need not be defined.
All intrinsic function arguments are intent(in) and so the intent for these arguments is not explicitly
given in the interface; however, the argument intent is explicitly specified for each argument of the
five intrinsic subroutines. The argument names can be used as actual argument keywords.
Many of the intrinsic procedures take array arguments of any rank. These arguments are shown as
rank one (:) in the following interfaces, and the descriptions identify which arguments may be
generic over rank and the resulting meaning of the different ranks.
abs (a)
elemental function abs(a) ! the |a|
real :: abs ! or integer if a is of type integer
real :: a ! or type integer or type complex
end function
If a is complex with value (x,y), abs returns an approximation to x2 + y2 .
achar (i)
elemental function achar(i) ! the ith ascii character
character :: achar ! the result kind is kind ('a')
integer :: i
end function
Note that achar(iachar(x)) is x for any character x of default kind represented by the processor.
acos (x)
elemental function acos(x) ! the arccosine (inverse cosine)
real :: acos
real :: x ! |x| ≤ 1
end function
The result has a value equal to a processor-dependent approximation to arccos(x), expressed in
radians. It lies in the range 0≤acos(x)≤π.
92 Fortran 90 Concise Reference
adjustl (string)
elemental function adjustl(string) ! remove leading blanks
character(len(string)) :: adjustl ! (the same number of trailing blanks added)
character(*) :: string
end function
adjustr (string)
elemental function adjustr(string) ! remove trailing blanks
character(len(string)) :: adjustr ! (the same number of leading blanks added)
character(*) :: string
end function
aimag (z)
elemental function aimag(z) ! imaginary part of z
real :: aimag ! if z = (x, y), aimag is y
complex :: z
end function
The result is scalar if dim is absent or mask has rank one; otherwise, the result is an array of rank
n-1 and of shape (d1,d2,...,ddim-1,ddim+1,...,dn) where (d1,d2,...,dn) is the shape of mask.
asin (x)
elemental function asin(x) ! the arcsine (inverse sine)
real :: asin
real :: x !x≤1
end function
The result has a value equal to a processor-dependent approximation to arcsin(x), expressed in
radians. It lies in the range -π/2≤asin(x)≤π/2.
associated (pointer, target)
inquiry function associated(pointer,target) ! check association status of argument
logical :: associated ! true if pointer is currently associated, else false
real, pointer :: pointer(:) ! pointer can be any type, any rank
real, optional :: target(:) ! target can be any type, any rank
end function
The actual argument for pointer must be a pointer with defined pointer association status. The
actual argument for target, if present, must be either a target or a pointer with defined pointer
association status. If target is absent, the result is true if pointer is currently associated with a
target and false otherwise. If target is present and is a target, the result is true if pointer is cur-
rently associated with target and false if it is not. If target is present and is a pointer, the result is
true if both pointer and target are currently associated with the same target, and false otherwise.
atan (x)
elemental function atan(x) ! the arctangent (inverse tangent)
real :: atan
real :: x
end function
The result has a value equal to a processor-dependent approximation to arctan(x), expressed in
radians, that lies in the range -π/2≤atan(x)≤π/2.
atan2 (y, x)
elemental function atan2(x) ! the arctangent (inverse tangent)
real :: atan2 ! of the nonzero complex number (x, y)
real :: y
real :: x
end function
The result has a value equal to a processor-dependent approximation to the arctan(y/x),
expressed in radians that lies in the range -π≤atan2(y,x)≤π. If y>0, the result is positive. If y=0,
the result is zero if x>0 and π if x<0. If y<0, the result is negative. If x=0, the absolute value of
the result is π/2.
bit_size (i)
inquiry function bit_size(i) ! number of bits in argument i
integer :: bit_size
integer :: i ! i may be an array of any rank
end function ! (but note extension in chapter 12)
ceiling (a)
elemental function ceiling(a) ! least integer greater than or equal to a
integer :: ceiling
real :: a
end function
cos (x)
elemental function cos(x) ! the cosine of x
real :: cos ! same type and kind as x
real :: x ! may be complex
end function
If x is of type real, it is regarded as a value in radians; if x is of type complex, its real part is
regarded as a value in radians.
cosh (x)
elemental function cosh(x) ! the hyperbolic cosine of x
real :: cosh
real :: x
end function
dim (x, y)
elemental function dim(x,y) ! returns max(0,x-y)
integer :: din ! same type and kind as x (and y)
integer :: x, y ! may also be real; y must have same type and kind as x
end function
96 Fortran 90 Concise Reference
epsilon (x)
inquiry function epsilon(x) ! a positive value almost negligible compared to unity
real :: epsilon ! same type and kind as x
real :: x ! may be any kind; may be an array of any rank
end function
exp (x)
elemental function exp(x) ! an approximation to ex
real :: exp ! type and kind of x
real :: x ! may be complex, in which case its imaginary part
end function ! is regarded as a value in radians
exponent (x)
elemental function exponent(x) ! the real model exponent part of x - see chapter 2
integer :: exponent
real :: x
end function
Intrinsic Procedures 97
floor (a)
elemental function floor(a) ! greatest integer less than or equal to a
integer :: floor
real :: a
end function
fraction (x)
elemental function fraction(x) ! the real model fractional part of x - see chapter 2
real :: fraction
real :: x
end function
huge (x)
inquiry function huge(x) ! the largest value for the type and kind of x
real :: huge ! same type and kind as x
real :: x ! may be any kind; may be integer; may be an array
end function
iachar (c)
elemental function iachar(c) ! same as ichar, except the ascii collating sequence
integer :: iachar ! (ISO 646:1983) is used instead of the processor’s
character :: c
end function
iand (i, j)
elemental function iand(i,j) ! perform logical and on bits of i and j
integer :: iand ! same kind as i (and j)
integer :: i, j ! any kind, but both must be the same kind
end function
The result is the bit-by-corresponding-bit and of the arguments; if both argument bits are 1 the
corresponding result bit is 1, otherwise the result bit is 0.
ibclr (i, pos)
elemental function ibclr(i,pos)
integer :: ibclr ! same as i, but with the specified bit set to 0
integer :: i ! may be any kind
integer :: pos ! position of bit in i to set to zero; 0≤pos<bit_size(i)
end function
ichar (c)
elemental function ichar(c) ! position of a character in the processor collating sequence
integer :: ichar
character :: c
end function ! same as iachar if the processor collating sequence is ascii
ieor (i, j)
elemental function ieor(i,j) ! perform logical exclusive-or on bits of i and j
integer :: ieor ! same kind as i (and j)
integer :: i, j ! any kind, but both must be the same kind
end function
The result is the bit-by-corresponding-bit exclusive-or of the arguments; if one of the argument
bits is 1 and the other is 0, the corresponding result bit is 1, otherwise the result bit is 0.
index (string, substring, back)
elemental function index(string,substring,back) ! search string for an substring of substring
integer :: index ! beginning position of substring in string (or zero)
character(*) :: string ! may be any kind
character(*) :: substring ! same kind as string
logical, optional :: back ! if present and true, search is from back of string
end function
If back is absent or present with the value false, the result is the minimum positive value of i
such that string(i:i+len(substring)–1) == substring or zero if there is no such value; if back is
present with the value true, the result is the maximum value of i less than or equal to len(string)–
len(substring)+1 such that string(i:i+len(substring)–1)==substring or zero if there is no such value.
Zero is returned if len(string)<len(substring) and one is returned if len(substring)==0.
int (a, kind)
elemental function int(a,kind) ! convert a to an integer value (of specified kind)
integer(kind) :: int ! the converted integer value
real :: a ! may be any numeric type
integer, optional :: kind ! if present, must be a scalar initialization expression
end function ! if kind is absent, the result kind is default integer
If a is of type integer, the result is this same value, but possibly of a different kind. If a is of type
real, the real value is truncated toward zero (e.g., int(3.7) is 3 and int(-3.7) is -3). If a is of type
complex, the result is int(real(a)).
ior (i, j)
elemental function ior(i,j) ! perform logical inclusive-or on bits of i and j
integer :: ior ! same kind as i (and j)
integer :: i, j ! any kind, but both must be the same kind
end function
The result is the bit-by-corresponding-bit inclusive-or of the arguments; if either one, or both,
of the argument bits is 1, the corresponding result bit is 1, otherwise the result bit is 0.
ishft (i, shift)
elemental function ishift(i,shift) ! logically end-off shift the bits of i the amount shift
integer :: ishft ! same kind as i
integer :: i ! may be any kind
integer :: shift ! amount to shift the bit pattern of i; shift must have a
end function ! magnitude less than or equal to bit_size(i)
The result is the value obtained by shifting the bits of i by shift positions. If shift is positive, the
shift is to the left. Bits shifted out are lost; zeros are shifted in at the opposite end.
Intrinsic Procedures 99
len_trim (string)
elemental function len_trim(string) ! same as len(trim(string))
integer :: len_trim ! the length of string with all trailing blanks removed
character(*) :: string
end function
log (x)
elemental function log(x) ! the natural logarithm, logex
real :: log ! same type and kind as x
real :: x ! may be complex; if real, x > 0
end function ! if complex, x must not be zero
log10 (x)
elemental function log10(x) ! base-10 logarithm, log10x
real :: log10 ! same kind as x
real :: x !x>0
end function
maxexponent (x)
inquiry function maxexponent(x) ! maximum model exponent that this kind of real can have
integer :: maxexponent
real :: x ! may be any kind; may be an array
end function
minexponent (x)
inquiry function minexponent(x) ! minimum model exponent that this kind of real can have
integer :: minexponent
real :: x ! may be any kind; may be an array
end function
102 Fortran 90 Concise Reference
mod (a, p)
elemental function mod(a,p) ! the remainder function (has sign of a)
integer :: mod ! same type and kind as a; value is a-int(a/p)*p
integer :: a ! any kind; may be real
integer :: p ! same type and kind as a; the value of p must not be zero
end function ! mod and modulo are the same for positive values of a and p
modulo (a, p)
elemental function modulo(a,p) ! the modulo function (has sign of p)
integer :: modulo ! same type and kind as a; value is a-floor(a/p)*p
integer :: a ! any kind; may be real
integer :: p ! same type and kind as a; the value of p must not be zero
end function ! mod and modulo are the same for positive values of a and p
not (i)
elemental function not(i) ! logical bit-wise complement
integer :: not ! the bit complement of i
integer :: i
end function ! 1 bits in i become 0 in not; 0 bits in i become 1 in not
present (a)
inquiry function present(a) ! determine whether an optional argument is present
logical :: present ! true if a is present, false otherwise
real :: a ! may be any type and kind; a must be an optional argument
end function ! of the procedure referencing the present function
random_number (harvest)
subroutine randon_number(harvet) ! generates one or more pseudorandom numbers
real, intent(out) :: harvest ! may be any kind, may be an array
end subroutine
104 Fortran 90 Concise Reference
If harvest is a scalar, a single pseudorandom number from the uniform distribution between 0
and 1 is generated and assigned to harvest; if harvest is an array, size(harvest) such numbers are
generated and assigned to harvest.
random_seed (size, put, get)
subroutine random_seed(size,put,get) ! set or retrieve the random_number seed
integer, optional, intent(out) :: size ! number of integers (n) used for the value of the seed
integer, optional, intent(in) :: put(:) ! size(put) must be equal to n; set the seed to put
integer, optional, intent(out) :: get(:) ! size(get) must be equal to n; retrieve the seed into get
end subroutine ! a given call to random_seed has at most one argument
If a call to random_seed is made without any arguments, the seed is set to an implementation-
determined value. When the argument is put, the seed is reinitialized to this value; when the
argument is get, the current value of the seed is retrieved.
range (x)
inquiry function range(x) ! decimal exponent range for x
integer :: range ! value is int(log10(huge(x))) - but see comment below
real :: x ! may be any kind, any numeric type; may be an array
end function
If x is of type integer, huge(x) returns an integer, which is not legal for log10; the effect for range
is, however, as if the equivalent real value had been returned for huge. If x is of type real the
value actually returned by range is min(int(log10(huge(x))),-int(log10(tiny(x)))).
real (a, kind)
elemental function real(a,kind) ! convert a to the equivalent real value of specified kind
real(kind) :: real ! the converted real value
real :: a ! may be any kind and any numeric type
integer, optional :: kind ! if present, must be a scalar initialization expression
end function ! if kind is absent, the result kind is default real
If a is of type real, the result is this same value, but possibly of a different kind. If a is an integer,
the equivalent real value is returned. If a is complex, the result is the real part of a.
repeat (string, ncopies)
function repeat(string,ncopies) ! concatenate several copies of a string
character(len(string)*ncopies) :: repeat ! ncopies of string concatenated ; same kind as string
character(*) :: string ! may be any kind
integer :: ncopies ! 0 ≤ ncopies
end function
rrspacing (x)
elemental function rrspacing(x) ! recipocal of the relative spacing of values near x
real :: rrspacing ! value is x/(nearest(x,1.)-x) for x > 0
real :: x
end function
scale (x, i)
elemental function scale(x,i) ! scales x by a specified amount
real :: scale ! same kind as x; value is x*radix(x)**i
real :: x ! may be any kind
integer :: i ! scaling may be up (i > 0) or down (i < 0) (or i may be zero)
end function
selected_int_kind (r)
function selected_int_kind(r) ! determines kind value for specifed integer range
integer :: selected_int_kind ! the kind value, or -1 if there is no such integer type
integer :: r ! specifies an integer range of at least -10**r to +10**r
end function
If more than one integer type meets the criteria, the kind value for the one with the smallest dec-
imal exponent range is returned or, if there are several such, the smallest of these kind values.
selected_real_kind (p, r)
function selected_real_kind(p,r) ! determines kind value for real type with specified properties
integer :: selected_real_kind ! the kind value, or a negative value if there is no such real type
integer, optional :: p ! specifies a real type with at least p decimal digits of precision
integer, optional :: r ! specifies an exponent range of at least 10**-r to 10**r
end function ! at least one argument must be present
The result is the kind type parameter of a real data type with decimal precision, as returned by
the precision function, of at least p digits and a decimal exponent range, as returned by the range
function, of at least r; if no such type is available on the processor, the result is –1 if the preci-
sion is not available, –2 if the exponent range is not available, and –3 if neither is available. If
more than one real type meets the criteria, the kind value for the one with the smallest decimal
precision is returned or, if there are several such, the smallest of these kind values.
set_exponent (x, i)
elemental function set_exponent(x,i) ! a value with the fractional part of x and exponent i
real :: set_exponent ! same kind as x; value is x*radix(x)**(i-exponent(x))
real :: x ! may be any kind
integer :: i ! i may be positive, negative, or zero
end function
shape (source)
inquiry function shape(source) ! determine the shape of an array
integer :: shape(:) ! element values are the extents of source
real :: source(:) ! may be any type, kind, and rank; may be scalar
end function
106 Fortran 90 Concise Reference
The value of the kth element of shape is the size of the kth dimension of source. size(shape) is n,
where n is the rank of source; if source is a scalar, n is zero. source must not be a dissassociated
pointer array, an unallocated allocatable array, or an assumed-size array.
sign (a, b)
elemental function sign(a,b) ! set the sign of a value
real :: sign ! value is |a| if b ≥ 0, -|a| if b < 0; type and kind of a
real :: a ! may be any kind; may be integer
real :: b ! same type and kind as a
end function
sin (x)
elemental function sin(x) ! the sine of x
real :: sin ! same type and kind as x
real :: x ! may be complex
end function
If x is of type real, it is regarded as a value in radians; if x is of type complex, its real part is
regarded as a value in radians.
sinh (x)
elemental function sinh(x) ! the hyperbolic sine of x;
real :: sinh
real :: x
end function
spacing (x)
elemental function spacing(x) ! absolute spacing near x
real :: spacing ! value is nearest(x,1.)-x for x > 0
real :: x
end function
sqrt (x)
elemental function sqrt(x) ! the square root of x
real :: sqrt ! same type and kind as x; value is x
real :: x ! may be complex
end function ! if x is of type real, x > 0
If x is complex, the real part of the result is nonnegative; if the real part is zero, the imaginary
part is nonnegative.
sum (array, dim, mask)
function sum(array,dim,mask) ! sum of the elements of array
real :: sum ! same type and kind as array
real :: array(:) ! may be any kind, any numeric type, and any rank
integer, optional :: dim ! if present, 1 ≤ dim ≤ n, where n is rank of array
logical, optional :: mask ! if present, mask must have same shape as array
end function
The result is scalar if dim is omitted or array has rank 1, in which case the value returned is the
sum of the elements of array. If array has rank n greater than 1 and dim is present, 1≤dim≤n and
dim specifies the dimension along which to compute the sums; in this case the result is an array
of rank n-1 and shape (d1,d2,...,ddim-1, ddim+1,...,dn) where (d1,d2,...,dn) is the shape of array and
each value of the result is the sum of the elements along the dim dimension of array. If mask is
present only those elements of array corresponding to the true values in mask are used in com-
puting the sum(s).
system_clock (count, count_rate, count_max)
subroutine system_clock(count,count_rate,count_max) ! integer data from a real-time clock
integer, intent(out), optional :: count ! 0 ≤ count ≤ count_max
integer, intent(out), optional :: count_rate ! clock counts per second
integer, intent(out), optional :: count_max ! the maximum count can have
end subroutine
All values are processor dependent; count_rate indicates how many times count is incremented
each second; when it reaches count_max, it resets to zero. If there is no processor clock count
always returns -huge(0), count_rate returns zero, and count_max returns zero.
tan (x)
elemental function tan(x) ! the tangent of x
real :: tan
real :: x ! value is assumed to be radians
end function
tanh (x)
elemental function tanh(x) ! the hyperbolic tangent of x
real :: tanh
real :: x
end function
tiny (x)
inquiry function tiny(x) ! the smallest positive value for the type and kind of x
real :: tiny ! same kind as x
real :: x ! may be any kind; may be an array
end function
108 Fortran 90 Concise Reference
trim (string)
function trim(string) ! removes trailing blanks from a string
character(*) :: trim ! same as string, except all trailing blanks removed
character(*) :: string ! may be any kind
end function
11 Syntax Rules
This chapter contains the complete syntax of Fortran 90. For reference purposes the syntax rules
are the same as in the Fortran 90 standard, with the same “R” (rule) numbers; however, the con-
straints are not included here.
Each syntax rule defines a term with the symbol is, optionally followed by alternative definitions
introduced by the symbol or. Optional parts of a definition are in closed in square brackets ( [ ] ),
and repeated parts are enclosed in square brackets followed by three dots ( [ ] ... ). Abbreviations
are used liberally (e.g., -stmt for statement) and any term ending with -list represents a comma-sepa-
rated list (e.g., xyz-list is an abbreviation for xyz [ , xyz ] ...); a term ending with -name is a name
(R304). Syntactic classes (nonterminals) are in italicized-font and literals are in bold. Literal words,
such as function are lower case, but upper-case letters are allowed. Where a syntax rule specifies
more than one line (statement) of actual code syntax, the rule for each code line is on a separate
syntax rule line (e.g., the if-construct, R802, involves multiple lines of actual code). In those few
cases where a syntax rule is too long to fit on one line, the “#” is used to indicate its continuation on
the next line (e.g., the syntax rule for the function statement, R1216, is too long to fit on one line).
or equivalence-stmt
or external-stmt
or intent-stmt
or intrinsic-stmt
or namelist-stmt
or optional-stmt
or pointer-stmt
or save-stmt
or target-stmt
R303 underscore is _
R708 power-op is **
R709 mult-op is *
or /
R710 add-op is +
or –
R712 concat-op is //
or .le.
or .gt.
or .ge.
or ==
or /=
or <
or <=
or >
or >=
R406 sign is +
or –
R415 exponent-letter is E
or D
R511 intent-spec is in
or out
or inout
R517 deferred-shape-spec is :
variables (R601-631)
R601 variable is scalar-variable-name
or array-variable-name
or subobject
expressions (R701-743)
R701 primary is constant
or constant-subobject
or variable
or array-constructor
or structure-constructor
or function-reference
or ( expr )
120 Fortran 90 Concise Reference
R708 power-op is **
R709 mult-op is *
or /
R710 add-op is +
or –
R712 concat-op is //
R1004 r is int-literal-constant
R1006 w is int-literal-constant
R1007 m is int-literal-constant
R1008 d is int-literal-constant
R1009 e is int-literal-constant
R1011 k is signed-int-literal-constant
R1012 position-edit-desc is Tn
or TL n
or TR n
or nX
R1013 n is int-literal-constant
R1014 sign-edit-desc is S
or SP
or SS
R1015 blank-interp-edit-desc is BN
or BZ
R1017 c is int-literal-constant
procedures (R1201-1226)
R1201 interface-block is interface-stmt
[ interface-body ] ...
[ module-procedure-stmt ] ...
end-interface-stmt
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
130 Fortran 90 Concise Reference
A Fortran 90 Implementation 131
12 A Fortran 90 Implementation
This chapter describes vendor-specific features of the Absoft Pro Fortran™ implementa-
tion of Fortran 90, including implementation-dependent values (kind values, I/O error val-
ues, etc.), language extensions, compiler directives, and command-line compiler options.
The implementation-dependent values will vary, but many of these extensions, directives,
and command-line options are typical of many commercial implementations.
implementation-dependent values
iostat= variable values for various i/o error conditions (trigger err=, if present)
language extensions
dec-style structures. A structure type is a data type extension that is similar to a sequence
derived type, but components of objects of structure types are guaranteed to be physically
stored in the order defined. Note that the terms “structure” and “structured object” refer to
an object of derived-type; the terms “structure type” and “structure definition” will be
used to refer to this extended type, and the terms “record” and “record object” will refer to
objects of this extended type. A structure definition has the form:
structure [/ structure-name / ] [record-list ]
abx-component-def
[ abx-component-def ]...
end structure
A union defines a data area which is shared by two or more groups of fields and has form
union
map-definition
map-definition ! note that a union must contain at least two map definitions
[ map-definition ]...
end union
where a map-definition is
map
field-declaration
[ field-declaration ]...
end map
134 Fortran 90 Concise Reference
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
where pointer-name is the name of the pointer variable being declared and target may be
any Fortran object, including a structure component, or an external function name. When
such a pointer is used as a dummy argument, the intent attribute applies to the pointer
value, not the value of the pointed-to object (if any).
The intrinsic functions loc and pointer are added (see below), each of which returns the
address (pointer value) of its argument.
An example serves to illustrate the use of this pointer type; note that strict type-checking
of pointer arguments may be relaxed in “unambiguous” cases:
A Fortran 90 Implementation 135
module Mytypes
type Rect; sequence
integer(2) :: top
end type
type Picture; sequence
integer(2) :: picSize
end type
end module
module Mod
interface
subroutine drawPicture(h_myPicture, dstRect)
use mytypes
type(Picture) :: myPicture
pointer(p_myPicture, myPicture) ! pointer to a derived-type object
pointer(h_myPicture, p_myPicture) ! pointer to a pointer
value :: h_myPicture ! pass the pointer by value
type(Rect) :: dstRect
end subroutine
end interface
end module
subroutine foobar
use Mod
type(Rect) :: dstRect
pointer (p,i)
call drawPicture(p,dstRect) ! legal - “p” is a pointer
call drawPicture(loc(j),dstRect) ! legal - type of ”loc” is pointer
call drawPicture(708089,dstRect) ! error - an integer constant is not a pointer
end ! (but may compile with a warning)
Pointer type matching is utilized, however, when resolving references to generic inter-
faces; for example:
interface bogus
subroutine point_bogus(p)
pointer (p,i)
end subroutine
subroutine real_bogus(z)
real z
end subroutine
subroutine int_bogus(i)
integer i
end subroutine
end interface
call bogus(0) ! reference to int_bogus
call bogus(loc(z)) ! reference to point_bogus
call bogus(1.0) ! reference to real_bogus
end
136 Fortran 90 Concise Reference
Record statements in a structure definition may specify targets of the type of the structure
being defined. For example, the following is legal:
structure /outer/ ! but this is illegal:
record /outer/ pointee ! structure /outer/
pointer (next, pointee) ! structure /outer/ pointee
... ! ...
end structure ! end structure
All of the records of such record statements (that specify the name of the structure being
defined) must appear as targets in pointer declarations in that structure, and forward refer-
ences to subsequent structure definitions are illegal. For example:
structure /outer/
structure /inone/
structure /intwo/
record /outer/ junk ! legal reference because of...
pointer (p_outer, junk) ! ...this pointer declaration
end structure
record /spaced/ nogood ! illegal forward reference
end structure
record /outer/ circle ! illegal - “circle” is not a pointer target
end structure
structure /spaced/
integer out
end structure
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
Attribute Extensions. Several attributes are added to the standard set of attributes:
attribute effect
automatic variable s are allocated on the stack; incompatible with static, save, and common
static equivalent to save, but statement form must have an object list
value applies to dummy arguments - specifies pass-by-value
volatile assignments and references occur, even if optimizations have eliminated these objects
stdcall standard calling sequence specified for procedures with this attributea
dll_import tags a procedure name as coming from a DLL
dll_export tags a procedure name as an entry to be exported to a DLL
a. The stdcall attribute keyword can, alternatively, be specified on the function or subroutine
statement, in the same manner as the recursive keyword; stdcall and recursive are mutually
exclusive - either one or the other, or neither, appears. If stdcall appears on a subroutine statement,
the parentheses for the optional dummy argument list must also appear (otherwise the statement
looks like, and is interpreted as, a stdcall attribute statement rather than a subroutine statement).
A Fortran 90 Implementation 137
These attributes can be specified either in type declarations statements, in the normal way,
or in attribute statements, with syntax similar to that for the standard attributes:
automatic [ [ :: ] sym-name-list ]
static [ :: ] sym-name-list
value [ :: ] sym-name-list
volatile [ [ :: ] sym-common-name-list ]
stdcall [ :: ] procedure-name-list
dll_import [ :: ] procedure-name-list
dll_export [ :: ] procedure-name-list
The name list is not required for the automatic and volatile statements, and if omitted that
attribute is applied to all of the local objects in the scope. A sym-name is an object name
and an sym-common-name in the volatile statement can be either an object name or / com-
mon-name /. The stdcall attribute can be specified only for external procedure names.
Module objects are inherently static/save, and automatic (or the stack directive) cannot be
specified within the scope of a module. Otherwise automatic and static take precedence
over save without a sym-name-list, the stack directive, and the -ev command-line option.
(Automatic is the same as the stack directive, and the -ev option is the same as save with-
out a sym-name-list.)
The value attribute is incompatible (must not be used) with these other attributes: external,
intent, intrinsic, optional, parameter, pointer, private, public, save and stdcall. If the inter-
face of a procedure having a value dummy argument is explicit, all associated actual argu-
ments will be passed by value.
The stdcall attribute is incompatible with these other attributes: allocatable, intent, param-
eter, pointer, target, save, and value. Stdcall functions cannot be: assumed-length (len=*),
variable length (len=n) character functions, array-valued functions, derived-type func-
tions, or storage associated in any way. The stdcall attribute can be applied only to exter-
nal procedure names, but not to: a function name specified in a result clause, a procedure
name specified by an entry statement, or a generic name specified in an interface block.
Because stdcall applies only to external functions, it is incompatible with: data initializa-
tion, namelist, statement functions, labels, block data, dll_import, and dll_export.
Stdcall is a platform-dependent extension specifically provided for direct communication
with the Windows Win32™ API; dll_import and dll_export are intended to interface with
DLLs that are not part of the Windows API. See also the compiler options -YIL, -
YDLL_STDCALL, and -YDDL_NAMES for compiler settings regarding these attributes.
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
138 Fortran 90 Concise Reference
function purpose Pa Eb
acosd, dacosdc x x
asind, dasindc x x
atand, datandc x x
atand, datan2dc x x
carg(expr) same as %val except for character argumentse; actual argument only
cdabs, i2abs, iiabs, jiabs specifics for generic abs x x
clock equivalent to date_and_time
cosd, dcosdc x x
cotan, dcotanc x x
cpu_time([time=] real-variable) subroutine; returns the processor time in seconds, as the argument value
date, jdate equivalent to date_and_time
eof([unit=] int-expr) returns .true. if unit is connected atf end of file; .false. otherwise
floati, floatj, dfloti, dflotj specifics for generic float x x
i2dim, iidim, jidim specifics for generic dim x x
i2max0, imax0, jmax0, imax1, jmax1, aimax0, ajmax0; purpose: specifics for generic max x
i2min0, imin0, jmin0, imin1, jmin1, aimin0, ajmin0; purpose: specifics for generic max x
i2mod, imod, jmod specifics for generic mod x x
i2nint, inint, jnint, iidnnt, jidnnt specifics for generic nint x x
i2sign,iisign, jisign specifics for generic sign x x
ibchng([inta=] int-expr, [intb=] int-expr) returns value of inta with bit intb reversed x
iiand, jiand specifics for generic iandd x x
function purpose Pa Eb
imag([z=] complex-expr) same as aimag; may be passed for default kind argument x x
inot, jnot specifics for generic notd x x
int2, int4, iifix, iint, jint, iidint, jidint, iifix, jifix purpose: specifics for generic int x
irtc, rtc equivalent to system_clock
isha([inta=] int-expr, [intb=] int-expr) shift inta the amount specified by intb (positive intb shifts left) x
ishc([inta=] int-expr, [intb=] int-expr) same as isha, but circular shift x
ishl([inta=] int-expr, [intb=] int-expr) same as isha, but logical shift x
izext, izext2, jzext, jzext2, jzext4 specifics for generic zext x x
loc, log10 extended so that can be passedd x x
sind, dsindc x x
tand, dtandc
zext(int-expr) returns the integer argument with no sign extension x
%loc(expr) the address of ref is passed; applies only to actual arguments
%val(expr) expr is passed by-values; applies only to actual arguments
The bit_size function is extended from the standard version, which allows only integer
objects as actual arguments; the extended version allows derived-type and structure-type
names (not objects) as actual arguments as well. In the case of derived-type and structure-
type names, the result is the number of bits any object of that type will occupy in memory
at runtime. For example:
type point
integer(kind=2) :: x, y, z
integer(kind=1) :: alpha, r, g, b
end type
...
print *, bit_size(Point) ! will output 80 on a Macintosh
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
140 Fortran 90 Concise Reference
Miscellaneous Extensions.
new open statement specifiers (last two are for the inquire statement)
specifier effect
form="binary" can be used only with sequential unformatted files - for stream I/O
access="window[,*]" for MacOS/MRWE™, the asterisk may be any string, checked at runtime
carriagecontrol={"Fortran"|"list"}
filetype=character-expr
creator=character-expr
convert={"big_endian"|"little_endian"}
access=character-variable "transparent" is a valid return value in the inquire statement
flen=default-integer-variable returns file length, in bytes, or zero if file is empty or nonexistent
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
If a character constant is appended with a C, as in "now is the time"C, then (a) a backslash
character (\) in the string is interpreted as an “escape character” that converts the subse-
quent character(s) in accordance with the following table and (b) appends a null character
(ascii 0) to the end of the string. The intent is to simulate C-style strings.
\a audible alarm (BEL, ascii 07) \t horizontal tab (HT, ascii 09)
\b backspace (BS, ascii 08) \v vertical tab (VT, ascii 11)
\f form feed (FF, ascii 12) \xh[h] hexadecimal digit(s), up to 2
\n newline (LF, ascii 10) \oo[o[o]] octal digit(s), up to 3
\r carriage return (CR, ascii 13) \\ backslash
Any such escape sequence, including the backslash character, is replaced with the indi-
cated character. If a backslash precedes any other character it is ignored (and removed).
The -YCSLASH command-line compiler option allows these escape sequences to be used
in any character constant (i.e., not just C-strings).
Subsequent use of the len intrinsic with a C-string value reflects the addition of the null;
for example, len("now\tis\nthe\ttime"C) has the value 16. Octal and hex values must fall in
the 0-255 (decimal) range, '\'C is illegal, C-strings may not appear in format statements,
and the character constant must be default kind.
A Fortran 90 Implementation 141
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
Expressions of type integer or pointer may be used as logical expressions in if statements
and constructs. The form if ( expr ) in such a context has the meaning if ( ( expr)/=0 ), where
expr is the integer or pointer expression.
Such expressions also can be used in logical assignment statements: logical-variable = expr,
with the (same) effect: logical-variable = (expr)/=0.
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
The keyword recursive may be omitted from a directly recursive procedure definition.
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
The = initialization-expr in a declaration statement may be replaced by / data-stmt-value / if
(and only if) that declaration statement does not contain the :: separator.
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
The byte type specifier is added and can be used anywhere the integer type specifier can be
used; it cannot have a kind value, and is equivalent to integer(1).
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
Tabs in columns 1-5 in fixed-form source are interpreted as follows:
- if the next character is a !, the line is a comment line,
- else if the next character is a nonzero digit (1-9) it is a continuation character,
- else the next character is the start of a statement.
If the -f alt_fixed compiler option is in effect, the interpretation is a bit different:
- if the next character is a letter (a-z or A-Z) it is the start of a statement,
- else the next character is in column 6, with the normal fixed-form interpretation.
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
For Absoft compilers running on systems other than Apple MacOS™, symbol names may
start with a leading dollar sign ($); for example: subroutine $foo(); end
Implicit typing of $ is default real, and in the implicit statement, $ is ordered after z; e.g.:
implicit integer (a-$) makes everything in the program type default integer, including, for
example, $foobar. (But note that names with leading dollar signs may not be the names of
variables associated with a namelist group.)
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
142 Fortran 90 Concise Reference
compiler directives
Compiler directives are placed on (separate) lines in the Fortran source code and provide
the compiler with additional information over that in the Fortran code itself. Directive
lines are identified by an initial token, !dir$, not shown in the following table, and appear
as comment lines. In fixed-form source Cdir$ also identifies a directive line, if the C is in
column 1. All directives, including the directive-identifying token, are case insensitive,
and ms$ and dec$ are acceptable alternatives to dir$ in all cases; in addition, if (and only
if) the -YMS7D compiler option is specified, the initial token may be simply $ in the first
column for the free[form], fixed[formlinesize], nofreeform, and pack directives, but this
form ($ in column 1) should be considered deprecated.
directive effect
attributes attr-list :: sym-list the possible attr values are:
alias, C, reference, stdcall, value, varying,
free[form] from this point on, source is free-form
nofreeform from this point on, source is fixed-form
fixed same as nofreeform
fixedformlinesize: {72|80|132} line length for fixed-form source
name (name="external-name") mapping between internal (Fortran) names and external (e.g., C) namesa
pack[on] [ = {1|2|4|mac68K} ] pack[on] and packoff specify that sequenced structure fields be aligned on byte,
packoff even byte, or word (four-byte) boundariesb ; default value is 1 (byte)
stack local scalar objects are allocated on the processor stack
a. The name directive can be applied to external procedure definitions as well as to external procedure names
(to put Fortran procedures into other language namespaces)..
b. The mac68k packing is for 68K-Pascal structures, which is character, integer(1), and logical(1) aligned on
byte boundaries; all other objects aligned on even-byte boundaries.
The packing directives affect the current program unit being compiled (if there is one), or
the next program unit (when there is no current program unit). The packing directive is
reset to the default (packoff) after the end of each program unit. A packing directive
affects only derived-types found below the directive in the source code.
The alignment of any derived-type object (i.e. not its components) is dependent on the
highest alignment bound of any component. This holds true for packed structs, unions,
and maps. A union embedded in a derived type will start on a boundary based on the most
restrictive member of the union (i.e. padding may be inserted before the base of a union
and all maps will start at the padded boundary).
A component with the pointer attribute has an alignment which is the same as the align-
ment the most restrictive of either a natural-word-sized integer or a machine address on
the target machine, regardless of the object type. For example, in type foo; character,
pointer :: p_c; end type foo has a 32-bit alignment on Pentium™ Pro and PowerPC™ 601.
A Fortran 90 Implementation 143
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
command-line compiler options
Compiler options are placed on the command line, following the command name (f90).
option effect
-c [<name>] compile to relocatable object code
-d {a|j|n|p|q|v|B|R} disable options (multiple options can be specified at once)a
-e {a|j|n|p|q|v|B|R} enable options (multiple options can be specified at once); same note as for -d
-f <form> source code format; <form> can be either free, fixed, or alt_fixed
-g produce debugging information for use with the debugger
-I <search-path> identify search path for include files; multiple search paths require multiple -I options
-o <name> specify compiler output file name
-O optimize the program for faster execution speed
-p <file> specify module files and/or directories
-s allocate user declared local variables with save (static) attribute
-v verbose compilation - echo all process commands used to create the output file(s)
-V output version number; can be used without file(s) or other options, for example: f90 -V
-w suppress all warnings
-W <line-length> line length for fixed form source; must be from the set {72,80,132}
-x <directive> disable specified source code directive; possible values are free, fixed, integer, name, stack
-YCHARV=ICHAR %val(char-entity) is passed as: %val(ichar(char-entity(1:1)));
default is to pass it as %val(%loc(char-entity))
-YCOM_NAMES= {UCS|LCS} specifies uppercase or lowercase for external common-block names; default is UCS
-YCOM_PFX [=prefix-string] specifies prefix (including null) for external common-block names; default is _C
-YCOM_SFX [=suffix-string] specifies suffix (including null) for external common-block names; default is null
-YCSLASH={0|1} if 1, any character constant can contain C-string backslash escapes sequences; default is 0
-YEXT_NAMES={ASIS|UCS|LCS} specifies the case of external procedure names; default is UCS
-YEXT_PFX [=prefix-string] specifies prefix (including null) for external representation of procedure names
-YEXT_SFX [=suffix-string] specifies suffix (including null) for external representation of procedure names
-YMS7D recognize Microsoft form of source code directive, which is $<directive> with the $ in column 1
-YNDFP=1 disallow use of period for component selection; default is that period can be used in place of %
-YPEI={0|1} 1 (the default) makes the pointer type equivalent to integer; 0 turns this off
144 Fortran 90 Concise Reference
option effect
\/---------------- MacOS/MPW™-specific options ----------------\/
-launch launch application after successful compilation
-link <arg> pass <arg> directly to linker
-mrwe make an MRWE™ application (the default)
-N9 forces generated code to make very frequent checks for command period
-plainappl make a plain application (i.e. don’t link MRWE™)
-ppc target the PowerPC™ architecture (the default)
-share use shared versions of intrinsic libraries and I/O libraries; default is to use static linkage
-tool make an MPW™ tool
-z <msg-level> suppress output message by level control (errors, warnings, cautions, notes, comments)b
-Z <msg-number-list> suppress the output of the specified messages (useful for turning off long warning lists)
\/---------------- Windows™/PC-specific options ----------------\/
-YDLL_NAMES={ASIS|UCS|LCS} default treatment of dll_import/dll_export names (see also -YIL=)
-YDLL_STDCALL={0|1} 0 means callee does not pop the argument frame; 1 means the frame is popped
-YIL={AC90,ACC,AC77,MSVC,MSVB,BC,BD,WINAPI} for dll_import/dll_export; see below
\/---------------- Unix™-specific options ----------------\/
-l <library> specify library names to linker
-L <path> search path for library names
-m <msg-level> same as -z <msg-level> in the Mac-specific options
-M<msg-number-list> same as -Z <msg-number-list> in the Mac-specific options
-r leave relocation information in file
-S produce an assembly source listing
-u <sym> force load of specified library name
-YCFRL={0|1} location of character length in argument list; 0 (default) at end of list, 1 after character value
The -YIL= Windows option controls the calling mechanism and name mangling used in
the machine code when creating LIB and DLL files. The following table summarizes the
effect of the various -YIL= option values:
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
Trademark acknowledgments:
Pro Fortran™ is a trademark of Absoft Corporation
MacOS™, MRWE™, and MPW™ are trademarks of Apple Computer
CF90™ is a trademark of Cray Research
VAX/VMS™ are trademarks of Digital Equipment
PowerPC™ is a trademark of IBM Corp used under license
Pentium™ is a trademark of Intel Corporation
Windows™ and Win32™ are trademarks of Microsoft Corporation
Unix™ is a trademark of Santa Cruz Organization
◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊ ◊
146 Fortran 90 Concise Reference
Index 147
Index
A reduction operations 25
Absoft, miscellaneous extensions 140 reshape, of a constructor 28
allocatable array 33 scalar subscript 31
section 30
argument association 77, 79 shape 25
actual argument 79 subscript 31
argument intent 81 triplet subscript 31
argument keyword 79, 81 upper bound 11
array element order 80 vector subscript 31, 32
array element sequence association 79 whole array operations 25
assumed-length dummy argument 79
assumed-shape dummy argument 79 assignment
assumed-size dummy argument 79 array 27
dummy argument 79 character 15
dummy procedure 81 masked array 28
explicit-shape dummy argument 79 numeric 14
for derived types 80 assignment statement 4
for equivalent types 80 assumed-shape dummy arguments 30
preventing nondeterminism 80 attribute extensions 136
type/kind match 79 attribute statements 3, 41
array 25 attributes
allocatable arrays 33 allocatable 12, 33
allocation status 33 compatiblity between 12
array-valued expressions 25 dimension 12
array-valued functions 26, 35 external 12
assignment 25, 27 intent 12
assumed size (deprecated) 45 intrinsic 12
assumed-shape dummy arguments 30 of data objects 12
automatic arrays 33 optional 12
broadcast, of scalars 26 parameter 12, 13, 27
computation functions 87 pointer 12, 34
conformable, conformability 25, 26 private 12
constant 27 public 12
constructor 25 save 12, 13, 33
constructors 27 target 12, 34
dimensions 11
element 30 B
element order 80
element-by-element operations 25, 26 bit
example, Gauss elimination 37 computation functions 87
example, picture refinement 36 intrinsic functions 6
implied-do, in constructors 27 pseudo data type 6
inquiry functions 25, 85 role of logical 9
lower bound 11 block data 2, 40, 43
mask 28 BNF, syntax rules 1
masked array assignment (where) 28
pointer arrays 33, 34 C
rank 26 character data type 9
148 Fortran 90 Concise Reference
records 47 count 94
repeat factor, for edit descriptors 52 cshift 35, 95
repeat factor, for input values 60 date_and_time subroutine 95
scratch files 54 dble 95
sequential files 54, 56 digits 7, 95
status variable (iostat=) 47 dim 95
unformatted 48, 50 dot_product 96
unit 47, 53 dprod 96
value separators 60 eoshift 96
int 8 epsilon 96
integer exp 96
operators 6 exponent 96
extensions 138
integer data type 5 floor 97
constant 5 fraction 97
expressions 6 huge 5, 97
kind 5 iachar 97
numeric computation functions 86 iand 97
integer division 6 ibclr 97
intent specifier 42 ibits 97
interface block 75, 82 ibset 97
interfaces, procedure 75 ichar 98
ieor 98
internal procedure (see procedures) 75 index 98
intrinsic data types 5 int 8, 14, 98
intrinsic functions ior 98
abs 91 ishft 98
achar 91 ishftc 99
acos 91 kind 5, 7, 8, 11, 14, 99
adjustl 92 lbound 99
adjustr 92 len 99
aimag 92 len_trim 99
aint 92 lge 99
all 92 lgt 99
allocated 33, 92 lle 100
alphabetical listing 88 llt 100
anint 92 log 100
any 92 log10 100
array inquiry functions 85 logical 100
asin 93 matmul 100
associated 34, 93 max 100
atan 93 maxexponent 101
atan2 93 maxloc 101
bit computation functions 6, 87 maxval 101
bit_size 93, 139 merge 101
btest 93 min 101
ceiling 94 minexponent 101
char 94 minloc 102
character computation functions 10, 86 minval 102
cmplx 8, 14, 94 miscellaneous inquiry functions 85
conjg 8, 94 mod 102
conversion functions 85 modulo 102
cos 94 mvbits subroutine 102
cosh 94 nearest 102
Index 151
parameter 42, 43 V
pointer 42, 43 value, pass by 137
private 42 variable 4
public 42
read 44, 47
return 84
rewind 56
save 40, 42, 43
statement function 84
stop 68
target 42, 43
use 43, 69
write 47, 49
statements (see also constructs) 4
storage association 39
storage unit
character 23, 40
numeric 8, 23, 40
unspecified 40
structure constructor 20
structure type (Absoft extension) 133
style, in examples 1
subroutine (see procedures) 75
subscript (see array) 31
substring (see character data type) 15
syntax rules 1, 109
control structures (R801-844) 122
data types (R401-435) 113
declarations and attributes (R501-549) 115
expressions (R701-743) 119
general structure (R201-216) 109
I/O formatting (R1001-1017) 126
input and output (R901-924) 124
procedures (R1201-1226) 128
program units (R1101-1112) 127
tokens (names, operators, etc.) R301-313
112
variables (R601-631) 118
T
type declaration 10
type specifier 10
U
use association 77
user-defined
operators 75
operators for derived types 22
types 17
154 Fortran 90 Concise Reference