An expression computes a value from constants, variables, function references and operators. Fortran 90 made arrays first-class: any operator or elemental function works on whole arrays.
Operator precedence
| Order | Operators | Notes |
|---|---|---|
| 1 (tightest) | defined unary operators (.inverse. a) | user-defined, one operand |
| 2 | ** | right to left: 2**3**2 is 2**9 |
| 3 | * / | left to right |
| 4 | unary + -; binary + - | -a**2 is -(a**2); a sign may not follow another operator (a * -b needs parentheses in the standard, though compilers allow it) |
| 5 | // | character concatenation |
| 6 | == /= < <= > >= and the .EQ. family | not associative: a < b < c is an error |
| 7 | .NOT. | |
| 8 | .AND. | |
| 9 | .OR. | |
| 10 | .EQV. .NEQV. | |
| 11 (loosest) | defined binary operators (a .cross. b) | user-defined, two operands |
The standard lets the processor evaluate an expression in any mathematically equivalent way, so a .and. f(x) need not skip f when a is false, and a * b / c may be rearranged. Parentheses force the order.
Types in expressions
- Mixed arithmetic converts the operand of lower rank to the higher one: integer, then real, then complex, and a higher kind within a type.
1/2is integer division and is0;1.0/2is0.5. **with an integer exponent is repeated multiplication; with a real exponent it needs a positive base.- Relational operators compare numbers (complex only for equality) and characters (by the collating sequence, with the shorter operand padded by blanks).
- Logical operators work on logicals;
.eqv.and.neqv.compare them. Bitwise operations on integers are intrinsic functions (iand,ior,ieor,not,ishft), not operators;.AND.on integers is an extension. - Character:
//joins,s(2:5)is a substring (positions 2 to 5),s(:3)ands(4:)leave an end out. A character assignment pads with blanks or truncates on the right. - Constant expressions (initialisation expressions) are the ones allowed in
parametervalues and kinds; specification expressions give array bounds and character lengths. Fortran 2003 and 2008 let more intrinsic functions appear in both.
Array syntax
An operation on arrays works on every element. The arrays must have the same shape (conform); a scalar is used with every element.
real :: a(10), b(10), c(10, 10)
a = 0.0 ! every element
a = b + 2.0 * sqrt(b) ! elementwise, and sqrt is elemental
c(1, :) = a ! the first row
c(:, 3) = b(10:1:-1) ! third column, filled from b reversed
a(2:8:2) = 1.0 ! elements 2, 4, 6, 8
a([1, 5, 9]) = -1.0 ! vector subscript
print *, sum(a), maxval(a), maxloc(a), size(c, 1)
lo:hi:strideis a section subscript; any part may be left out (:is the whole dimension)- a vector subscript is an integer array giving the elements in order, and may repeat them when it is not assigned to
- an elemental procedure applied to an array works element by element: all the numeric intrinsics, and user functions declared
elemental - a transformational intrinsic (
sum,matmul,reshape,pack,spread) turns arrays into a new array or a scalar; see Intrinsic procedures - assignment to an
allocatablearray reallocates it to the shape of the value (Fortran 2003, switched off by-fno-realloc-lhsin GNU Fortran)
Array and structure constructors
v = [1, 2, 3] ! Fortran 2003 brackets
v = (/ 1, 2, 3 /) ! the Fortran 90 spelling
squares = [(i*i, i = 1, 10)] ! implied do
names = [character(len=5) :: 'ann', 'bob']
z = [real :: 1, 2.5] ! type given, so the values convert
m = reshape([1, 2, 3, 4, 5, 6], [2, 3])
p = point(1.0, 2.0) ! structure constructor
A constructor with the type before :: is how an array of strings gets one length, and how a real array can be built from integers. The viewer colours that type name as a type.
WHERE, FORALL and masks
where (a > 0.0)
b = sqrt(a)
elsewhere (a == 0.0)
b = 0.0
elsewhere
b = -1.0
end where
where (a < 0.0) a = 0.0 ! one-line form
forall (i = 1:n, j = 1:n, i /= j) c(i, j) = a(i) * b(j)
do concurrent (i = 1:n, a(i) /= 0.0)
b(i) = 1.0 / a(i)
end do
where assigns only where the mask is true (Fortran 90; the construct may have several elsewhere masks from Fortran 95). forall was added in Fortran 95 for array-like loops and is obsolescent in Fortran 2018; do concurrent (Fortran 2008) replaces it.
Many intrinsics take a mask= argument, and merge(a, b, mask) chooses elementwise.
Components, pointers and coarrays
a%bselects a component;a(i)%b(j)anda%b(2:3)mix subscripts and components;%is the Fortran 90 spelling of the selector (DEC used.)- pointer assignment is
p => t; a pointer array can be remapped:p(0:n-1) => a(Fortran 2003) andp(1:m, 1:n) => a(Fortran 2008 for rank change) - an expression naming an image:
a[3],a(2)[1, 2](Fortran 2008). See Parallel features
Defined operators and assignment
interface operator(+)
module procedure add_money
end interface
interface operator(.dot.)
module procedure dot_vec
end interface
interface assignment(=)
module procedure money_from_real
end interface
total = a + b ! calls add_money
d = u .dot. v
+, defining a new operator and defining assignment for a type.A defined operator is a function with one or two intent(in) arguments, and defined assignment is a subroutine with two (intent(out) or intent(inout) for the left side).
The interface may name an intrinsic operator (+, ==, //) to extend it to a derived type, or a new .name.. Type-bound forms are in
Derived types and objects.
Conditional expressions (Fortran 2023)
y = (x > 0 ? x : -x) ! like a conditional operator
level = (n < 10 ? 1 : n < 100 ? 2 : 3) ! chained
A parenthesised condition ? value : value evaluates only the chosen branch, so it can guard an optional argument or an array subscript. The same syntax is allowed for actual arguments, where a
branch may leave an optional argument absent. The viewer shows the ? and : characters plain. This is new in the 2023 revision.