BLOCK
construct allows declarations of entities within executable
code.
For example,
Do i=1,n Block Real tmp tmp = a(i)**3 If (tmp>b(i)) b(i) = tmp End Block End DoHere the variable
tmp
has its scope limited to the BLOCK
construct, so will not affect anything outside it.
This is particularly useful when including code by INCLUDE
or by
macro preprocessing.
All declarations are allowed within a BLOCK
construct except for
COMMON
, EQUIVALENCE
, IMPLICIT
, INTENT
,
NAMELIST
, OPTIONAL
and VALUE
; also, statement function
definitions are not permitted.
BLOCK
constructs may be nested; like other constructs, branches into a
BLOCK
construct from outside are not permitted.
A branch out of a BLOCK
construct “completes” execution of the
construct.
Entities within a BLOCK
construct that do not have the SAVE
attribute (including implicitly via initialisation), will cease to exist when
execution of the construct is completed.
For example, an allocated ALLOCATABLE
variable will be automatically
deallocated, and a variable with a FINAL
procedure will be finalised.
EXIT
statement is no longer restricted to exiting from a DO
construct; it can now be used to jump to the end of a named ASSOCIATE
,
BLOCK
, IF
, SELECT CASE
or SELECT TYPE
construct
(i.e. any named construct except FORALL
and WHERE
).
Note that an EXIT
statement with no construct-name still exits from
the innermost DO
construct, disregarding any other named constructs it
might be within.
STOP
statement, the stop-code may be any scalar constant
expression of type integer or default character.
(In the NAG Fortran Compiler this also applies to the PAUSE
statement,
but that statement is no longer standard Fortran.)
Additionally, the STOP
statement with an integer stop-code now
returns that value as the process exit status (on most operating systems there
are limits on the value that can be returned, so for the NAG Fortran Compiler
this returns only the lower eight bits of the value).
ERROR STOP
statement has been added.
This is similar to the STOP
statement, but causes error termination
rather than normal termination.
The syntax is identical to that of the STOP
statement apart from the
extra keyword ‘ERROR
’ at the beginning.
Also, the default process exit status is zero for normal termination, and
non-zero for error termination.
For example,
IF (x<=0) ERROR STOP 'x must be positive'
FORALL
construct now has an optional type specifier in the initial
statement of the construct, which can be used to specify the type (which must
be INTEGER
) and kind of the index variables.
When this is specified, the existence or otherwise of any entity in the outer
scope that has the same name as an index variable does not affect the index
variable in any way.
For example,
Complex i(100) Real x(200) ... Forall (Integer :: i=1:Size(x)) x(i) = i
Note that the FORALL
construct is still not recommended for high performance,
as the semantics imply evaluating the right-hand sides into array temps the
size of the iteration space, and then assigning to the variables; this usually
performs worse than ordinary DO
loops.
DO CONCURRENT
construct is a DO
loop with restrictions and
semantics intended to allow efficient execution.
The iterations of a DO CONCURRENT
construct may be executed in any
order, and possibly even in parallel.
The loop index variables are local to the construct.
The DO CONCURRENT
header has similar syntax to the FORALL
header,
including the ability to explicitly specify the type and kind of the loop index
variables, and including the scalar mask.
The restrictions on the DO CONCURRENT
construct are:
RETURN
and STOP
statements, but ERROR STOP
is allowed);
EXIT
statement cannot be used to terminate the loop;
CYCLE
statement cannot refer to an outer loop;
IEEE_GET_FLAG
or IEEE_SET_HALTING_MODE
is allowed.
For example,
Integer vsub(n) ... Do Concurrent (i=1:n) ! Safe because vsub has no duplicate values. x(vsub(i)) = i End Do
The full syntax of the DO CONCURRENT
statement is:
[ do-construct-name :
] DO
[ label ] [,
] CONCURRENT
forall-header
(
[ integer-type-spec ::
] triplet-spec [,
triplet-spec ]... [,
mask-expr ] )
name = expr : expr [ : expr ]