(5) the allocation transfer procedure (16.9.137) is executed, the pointer is associated with the argument
FROM, and the argument TO does not have the TARGET attribute,
(6) completion of execution of an instance of a subprogram causes the pointer’s target to become un-
defined (item (3) of 19.6.6),
(7) completion of execution of a BLOCK construct causes the pointer’s target to become undefined (item
(23) of 19.6.6),
(8) execution of the host instance of a procedure pointer is completed,
(9) execution of an instance of a subprogram completes and the pointer is declared or accessed in the
subprogram that defines the procedure if the pointer
(a) does not have the SAVE attribute,
518 ⃝c ISO/IEC 2017 – All rights reserved
ISO/IEC DIS 1539-1:2017 (E)
(b) is not in blank common, (c) is not in a named common block that is declared in any other scoping unit that is in execution, (d) is not accessed by host association, and (e) is not the result of a function declared to have the POINTER attribute, (10) execution of an instance of a subprogram completes, the pointer is associated with a dummy argument of the procedure, and(11) a BLOCK construct completes execution and the pointer is an unsaved construct entity of that(a) the effective argument does not have the TARGET attribute or is an array section with a
vector subscript, or
(b) the dummy argument has the VALUE attribute,
BLOCK construct,(12) a DO CONCURRENT construct is terminated and the pointer’s association status was changed in
more than one iteration of the construct,(13) an iteration of a DO CONCURRENT construct completes and the pointer is associated with a
variable of that construct that has LOCAL or LOCAL_INIT locality,(14) the pointer is a subcomponent of an object that is allocated and either
(a) the pointer is not default-initialized and SOURCE= does not appear, or(15) the pointer is a subcomponent of an object, the pointer is not default-initialized, and a procedure is(b) SOURCE= appears and the association status of the corresponding subcomponent of source-
expr is undefined,
invoked with this object as an actual argument corresponding to a dummy argument with INTENT(16) a procedure is invoked with the pointer as an actual argument corresponding to a pointer dummy(OUT),
argument with INTENT (OUT), or(17) evaluation of an expression containing a function reference that need not be evaluated completes, if
execution of that function would change the association status of the pointer.
<IP_ADDRESS> Other events that change the association status of pointers 1 When a pointer becomes associated with another pointer by argument association, construct association, or host association, the effects on its association status are specified in <IP_ADDRESS> While two pointers are name associated, storage associated, or inheritance associated, if the association status of
one pointer changes, the association status of the other changes accordingly.3 The association status of a pointer object with the VOLATILE attribute might change by means not specified
by the program.1 The definition status of an associated pointer is that of its target. If a pointer is associated with a definable<IP_ADDRESS> Pointer definition status
target, it may be defined or become undefined according to the rules for a variable (19.6). The definition status1 If the association status of a pointer is disassociated or undefined, the pointer shall not be referenced or dealloc-of a pointer that is not associated is undefined.
⃝c ISO/IEC 2017 – All rights reserved 519
ISO/IEC DIS 1539-1:2017 (E)
<IP_ADDRESS> Relationship between association status and definition status
ated. Whatever its association status, a pointer always may be nullified, allocated, or pointer-assigned. A nullified1 Storage sequences are used to describe relationships that exist among variables and common blocks. Storage asso-pointer is disassociated. When a pointer is allocated, it becomes associated but undefined. When a pointer is
pointer-assigned, its association and definition status become those of the specified data-target or proc-target.
19.5.3 Storage association
<IP_ADDRESS> General
ciation is the association of two or more data objects that occurs when two or more storage sequences share or1 A storage sequence is a sequence of storage units. The size of a storage sequence is the number of storage unitsare aligned with one or more storage units.
<IP_ADDRESS> Storage sequence
in the storage sequence. A storage unit is a character storage unit, a numeric storage unit, a file storage unit2 In a storage association context(12.3.5), or an unspecified storage unit. The sizes of the numeric storage unit, the character storage unit and the
file storage unit are the values of constants in the ISO_FORTRAN_ENV intrinsic module (16.10.2).
(1) a nonpointer scalar object that is default integer, default real, or default logical occupies a single3 A sequence of storage sequences forms a storage sequence. The order of the storage units in such a compositenumeric storage unit,
(2) a nonpointer scalar object that is double precision real or default complex occupies two contiguous
numeric storage units,
(3) a default character nonpointer scalar object of character length len occupies len contiguous character
storage units,
(4) if C character kind is not the same as default character kind a nonpointer scalar object of type char-
acter with the C character kind (18.2.2) and character length len occupies len contiguous unspecified
storage units,
(5) a nonpointer scalar object of sequence type occupies a sequence of storage sequences corresponding
to the sequence of its ultimate components,
(6) a nonpointer scalar object of any type not specified in items (1)-(5) occupies a single unspecified
storage unit that is different for each case and each set of type parameter values, and that is different
from the unspecified storage units of item (4),
(7) a nonpointer array occupies a sequence of contiguous storage sequences, one for each array element,
in array element order (<IP_ADDRESS>), and
(8) a data pointer occupies a single unspecified storage unit that is different from that of any nonpointer
object and is different for each combination of type, type parameters, and rank. A data pointer that
has the CONTIGUOUS attribute occupies a storage unit that is different from that of a data pointer
that does not have the CONTIGUOUS attribute.
storage sequence is that of the individual storage units in each of the constituent storage sequences taken in4 Each common block has a storage sequence (<IP_ADDRESS>).succession, ignoring any zero-sized constituent sequences.
520 ⃝c ISO/IEC 2017 – All rights reserved
ISO/IEC DIS 1539-1:2017 (E)
<IP_ADDRESS> Association of storage sequences1 Two nonzero-sized storage sequences s1 and s2 are storage associated if the ith storage unit of s1 is the same as
the jth storage unit of s2 . This causes the (i + k)th storage unit of s1 to be the same as the (j + k)th storage2 Storage association also is defined between two zero-sized storage sequences, and between a zero-sized storageunit of s2 , for each integer k such that 1 ≤ i + k ≤ size of s1 and 1 ≤ j + k ≤ size of s2 where size of measures
the number of storage units.
sequence and a storage unit. A zero-sized storage sequence in a sequence of storage sequences is storage associated1 Two scalar data objects are storage associated if their storage sequences are storage associated. Two scalar entitieswith its successor, if any. If the successor is another zero-sized storage sequence, the two sequences are storage
associated. If the successor is a nonzero-sized storage sequence, the zero-sized sequence is storage associated with
the first storage unit of the successor. Two storage units that are each storage associated with the same zero-sized
storage sequence are the same storage unit.
<IP_ADDRESS> Association of scalar data objects
are totally associated if they have the same storage sequence. Two scalar entities are partially associated if they2 The definition status and value of a data object affects the definition status and value of any storage associatedare associated without being totally associated.
entity. An EQUIVALENCE statement, a COMMON statement, or an ENTRY statement can cause storage association of storage3 An EQUIVALENCE statement causes storage association of data objects only within one scoping unit, unless one of the equivalencedsequences.
entities is also in a common block (<IP_ADDRESS>, <IP_ADDRESS>).4 COMMON statements cause data objects in one scoping unit to become storage associated with data objects in another scoping unit.
5 A common block is permitted to contain a sequence of differing storage units. All scoping units that access named common blocks
with the same name shall specify an identical sequence of storage units. Blank common blocks may be declared with differing sizes6 An ENTRY statement in a function subprogram causes storage association of the function results that are variables.in different scoping units. For any two blank common blocks, the initial sequence of storage units of the longer blank common block
shall be identical to the sequence of storage units of the shorter common block. If two blank common blocks are the same length,
they shall have the same sequence of storage units.
7 Partial association shall exist only between
• an object that is default character or of character sequence type and an object that is default character or8 For noncharacter entities, partial association may occur only through the use of COMMON, EQUIVALENCE, or ENTRY statements.of character sequence type, or
• an object that is default complex, double precision real, or of numeric sequence type and an object that is
default integer, default real, default logical, double precision real, default complex, or of numeric sequence
type.
For character entities, partial association may occur only through argument association or the use of COMMON or9 Partial association of character entities occurs when some, but not all, of the storage units of the entities are theEQUIVALENCE statements.
⃝c ISO/IEC 2017 – All rights reserved 521
ISO/IEC DIS 1539-1:2017 (E)
same.10 A storage unit shall not be explicitly initialized more than once in a program. Explicit initialization overrides
default initialization, and default initialization for an object of derived type overrides default initialization for1 Inheritance association occurs between components of the parent component and components inherited by typea component of the object (<IP_ADDRESS>). Default initialization may be specified for a storage unit that is storage
associated provided the objects supplying the default initialization are of the same type and type parameters,
and supply the same value for the storage unit.
19.5.4 Inheritance association
extension into an extended type (<IP_ADDRESS>). This association is persistent; it is not affected by the accessibility of1 When an association is established between two entities by argument association, host association, or constructthe inherited components.
19.5.5 Establishing associations
association, certain properties of the associating entity become those of the pre-existing entity.2 For argument association, the pre-existing entity is the effective argument and the associating entity is the dummy
argument.3 For host association, the associating entity is the entity in the contained scoping unit. When a procedure is
invoked, the pre-existing entity that participates in the association is the one from its host instance (<IP_ADDRESS>).4 For construct association, the associating entity is identified by the associate name and the pre-existing entity isOtherwise the pre-existing entity that participates in the association is the entity in the host scoping unit.
the selector.5 When an association is established by argument association, host association, or construct association, the fol-
lowing applies.• If the entities have the POINTER attribute, the pointer association status of the associating entity becomes
the same as that of the pre-existing entity. If the pre-existing entity has a pointer association status of
associated, the associating entity becomes pointer associated with the same target and, if they are arrays,
the bounds of the associating entity become the same as those of the pre-existing entity.
• If the associating entity has the ALLOCATABLE attribute, its allocation status becomes the same as that
of the pre-existing entity. If the pre-existing entity is allocated, the bounds (if it is an array), values of
deferred type parameters, definition status, and value (if it is defined) become the same as those of the
pre-existing entity. If the associating entity is polymorphic and the pre-existing entity is allocated, the
dynamic type of the associating entity becomes the same as that of the pre-existing entity.
• If the associating entity is neither a pointer nor allocatable, its definition status, value (if it is defined), and
dynamic type (if it is polymorphic) become the same as those of the pre-existing entity. If the entities are
arrays and the association is not argument association, the bounds of the associating entity become the
same as those of the pre-existing entity.
• If the associating entity is a pointer dummy argument and the pre-existing entity is a nonpointer actual
argument the associating entity becomes pointer associated with the pre-existing entity and, if the entities
are arrays, the bounds of the associating entity become the same as those of the pre-existing entity.
522 ⃝c ISO/IEC 2017 – All rights reserved
ISO/IEC DIS 1539-1:2017 (E)
19.6 Definition and undefinition of variables 19.6.1 Definition of objects and subobjects 1 A variable may be defined or may be undefined and its definition status may change during execution of a
program. An action that causes a variable to become undefined does not imply that the variable was previously2 Arrays, including sections, and variables of derived, character, or complex type are objects that consist of zerodefined. An action that causes a variable to become defined does not imply that the variable was previously
undefined.
or more subobjects. Associations may be established between variables and subobjects and between subobjects3 An array is defined if and only if all of its elements are defined.of different variables. These subobjects may become defined or undefined.
4 A derived-type scalar object is defined if and only if all of its nonpointer components are defined.
5 A complex or character scalar object is defined if and only if all of its subobjects are defined.
6 If an object is undefined, at least one (but not necessarily all) of its subobjects are undefined.
19.6.2 Variables that are always defined1 Zero-sized arrays and zero-length strings are always defined.
19.6.3 Variables that are initially defined1 The following variables are initially defined:
(1) variables specified to have initial values by DATA statements;NOTE 19.11(2) variables specified to have initial values by type declaration statements;
(3) nonpointer default-initialized subcomponents of saved variables that do not have the ALLOCAT-
ABLE or POINTER attribute;
(4) pointers specified to be initially associated with a variable that is initially defined;
(5) variables that are always defined;
(6) variables with the BIND attribute that are initialized by means other than Fortran.
Fortran code:
module mod
integer, bind(c,name="blivet") :: fooend module mod
C code:
int blivet = 123;
In the above example, the Fortran variable foo is initially defined to have the value 123 by means other
than Fortran.
⃝c ISO/IEC 2017 – All rights reserved 523
ISO/IEC DIS 1539-1:2017 (E)
19.6.4 Variables that are initially undefined 1 Variables that are not initially defined are initially undefined. 19.6.5 Events that cause variables to become defined1 Variables become defined by the following events.
(1) Execution of an intrinsic assignment statement other than a masked array assignment or FORALLassignment statement causes the variable that precedes the equals to become defined.
(2) Execution of a masked array assignment or FORALL assignment statement might cause some or all of
the array elements in the assignment statement to become defined (10.2.3).
(3) As execution of an input statement proceeds, each variable that is assigned a value from the input
file becomes defined at the time that data are transferred to it. (See (4) in 19.6.6.) Execution of a
WRITE statement whose unit specifier identifies an internal file causes each record that is written
to become defined.
(4) Execution of a DO statement causes the DO variable, if any, to become defined.
(5) Beginning of execution of the action specified by an io-implied-do in a synchronous data transfer
statement causes the do-variable to become defined.
(6) A reference to a procedure causes an entire dummy data object to become defined if the dummy data
object does not have INTENT (OUT) and the entire effective argument is defined.
A reference to a procedure causes a subobject of a dummy argument to become defined if the dummy
argument does not have INTENT (OUT) and the corresponding subobject of the effective argument
is defined.
(7) Execution of an input/output statement containing an IOSTAT= specifier causes the specified integer
variable to become defined.
(8) Execution of a synchronous input statement containing a SIZE= specifier causes the specified integer
variable to become defined.
(9) Execution of a wait operation (12.7.1) corresponding to an asynchronous input statement containing
a SIZE= specifier causes the specified integer variable to become defined.
(10) Execution of an INQUIRE statement causes any variable that is assigned a value during the execution
of the statement to become defined if no error condition exists.
(11) If an error, end-of-file, or end-of-record condition occurs during execution of an input/output state-
ment that has an IOMSG= specifier, the iomsg-variable becomes defined.
(12) When a character storage unit becomes defined, all associated character storage units become defined.
When a numeric storage unit becomes defined, all associated numeric storage units of the same type
become defined. When an entity of double precision real type becomes defined, all totally associated
entities of double precision real type become defined.
When an unspecified storage unit becomes defined, all associated unspecified storage units become
defined.
(13) When a default complex entity becomes defined, all partially associated default real entities become
defined.
(14) When both parts of a default complex entity become defined as a result of partially associated default
real or default complex entities becoming defined, the default complex entity becomes defined.
524 ⃝c ISO/IEC 2017 – All rights reserved
ISO/IEC DIS 1539-1:2017 (E)(15) When all components of a structure of a numeric sequence type or character sequence type become
defined as a result of partially associated objects becoming defined, the structure becomes defined.(16) Execution of a statement with a STAT= specifier causes the variable specified by the STAT= specifier
to become defined.(17) If an error condition occurs during execution of a statement that has an ERRMSG= specifier, the
variable specified by the ERRMSG= specifier becomes defined.(18) Allocation of a zero-sized array or zero-length character variable causes the array or variable to
become defined.(19) Allocation of an object that has a nonpointer default-initialized subcomponent, except by an AL-
LOCATE statement with a SOURCE= specifier, causes that subcomponent to become defined.(20) Successful execution of an ALLOCATE statement with a SOURCE= specifier causes a subobject of
the allocated object to become defined if the corresponding subobject of the SOURCE= expression(21) Invocation of a procedure causes any automatic data object of zero size or zero character length inis defined.
that procedure to become defined.(22) When a pointer becomes associated with a target that is defined, the pointer becomes defined.
(23) Invocation of a procedure that contains an unsaved nonpointer nonallocatable local variable causes
all nonpointer default-initialized subcomponents of the object to become defined.(24) Invocation of a procedure that has a nonpointer nonallocatable INTENT (OUT) dummy argument
causes all nonpointer default-initialized subcomponents of the dummy argument to become defined.(25) In a DO CONCURRENT or FORALL construct, the index-name becomes defined when the index-
name value set is evaluated.(26) In a DO CONCURRENT construct, a variable with LOCAL_INIT locality becomes defined at the
beginning of each iteration.(27) An object with the VOLATILE attribute that is changed by a means not specified by the program
might become defined (see 8.5.19).(28) Execution of the BLOCK statement of a BLOCK construct that has an unsaved nonpointer non-
allocatable local variable causes all nonpointer default-initialized subcomponents of the variable to(29) Execution of an OPEN statement containing a NEWUNIT= specifier causes the specified integerbecome defined.
variable to become defined.(30) Execution of a LOCK statement containing an ACQUIRED_LOCK= specifier causes the specified
logical variable to become defined. If the logical variable becomes defined with the value true, the(31) Successful execution of a LOCK statement that does not contain an ACQUIRED_LOCK= specifierlock variable in the LOCK statement also becomes defined.
causes the lock variable to become defined.(32) Successful execution of an UNLOCK statement causes the lock variable to become defined.
(33) Failure of an image that locked a lock variable without unlocking it causes the lock variable to become
defined.(34) Successful execution of an EVENT POST or EVENT WAIT statement causes the event variable to
become defined.(35) Successful execution of a FORM TEAM statement causes the team variable to become defined.
⃝
c ISO/IEC 2017 – All rights reserved 525
ISO/IEC DIS 1539-1:2017 (E)1 Variables become undefined by the following events.19.6.6 Events that cause variables to become undefined
(1) When a scalar variable of intrinsic type becomess defined, all totally associated variables of different type becomeundefined. When a double precision scalar variable becomes defined, all partially associated scalar
variables become undefined. When a scalar variable becomes undefined, all partially associated double
precision scalar variables become undefined.
(2) If the evaluation of a function would cause a variable to become defined and if a reference to the
function appears in an expression in which the value of the function is not needed to determine the
value of the expression, the variable becomes undefined when the expression is evaluated.
(3) When execution of an instance of a subprogram completes,
(a) its unsaved local variables become undefined,
(b) unsaved variables in a named common block that appears in the subprogram become undefined if they have been
defined or redefined, unless another active scoping unit is referencing the common block, and
(c) a variable of type C_PTR from the intrinsic module ISO_C_BINDING whose value is the C
address of an unsaved local variable of the subprogram becomes undefined.
(4) When an error condition or end-of-file condition occurs during execution of an input statement, all of
the variables specified by the input list or namelist group of the statement become undefined.
(5) When an error condition occurs during execution of an output statement in which the unit is an internal
file, the internal file becomes undefined.
(6) When an error condition, end-of-file condition, or end-of-record condition occurs during execution of
an input/output statement and the statement contains any io-implied-dos, all of the do-variables in
the statement become undefined (12.11).
(7) Execution of a direct access input statement that specifies a record that has not been written previously
causes all of the variables specified by the input list of the statement to become undefined.
(8) Execution of an INQUIRE statement might cause the NAME=, RECL=, and NEXTREC= variables
to become undefined (12.10).
(9) When a character storage unit becomes undefined, all associated character storage units become un-
defined.
When a numeric storage unit becomes undefined, all associated numeric storage units become undefined
unless the undefinition is a result of defining an associated numeric storage unit of different type (see
(1) above).
When an entity of double precision real type becomes undefined, all totally associated entities of double
precision real type become undefined.
When an unspecified storage unit becomes undefined, all associated unspecified storage units become
undefined.
(10) When an allocatable entity is deallocated, it becomes undefined.
(11) When the allocation transfer procedure (16.9.137) causes the allocation status of an allocatable entity
to become unallocated, the entity becomes undefined.
(12) Successful execution of an ALLOCATE statement with no SOURCE= specifier causes a subcomponent
of an allocated object to become undefined if default initialization has not been specified for that
subcomponent.
526 ⃝c ISO/IEC 2017 – All rights reserved
ISO/IEC DIS 1539-1:2017 (E)(13) Successful execution of an ALLOCATE statement with a SOURCE= specifier causes a subobject of
the allocated object to become undefined if the corresponding subobject of the SOURCE= expression(14) Execution of an INQUIRE statement causes all inquiry specifier variables to become undefined if anis undefined.
error condition exists, except for any variable in an IOSTAT= or IOMSG= specifier.(15) When a procedure is invoked
(a) an optional dummy argument that has no corresponding actual argument becomes undefined,(16) When the association status of a pointer becomes undefined or disassociated (<IP_ADDRESS>, <IP_ADDRESS>), the(b) a dummy argument with INTENT (OUT) becomes undefined except for any nonpointer default-
initialized subcomponents of the argument,
(c) an actual argument corresponding to a dummy argument with INTENT (OUT) becomes un-
defined except for any nonpointer default-initialized subcomponents of the argument,
(d) a subobject of a dummy argument that does not have INTENT (OUT) becomes undefined if the
corresponding subobject of the effective argument is undefined, and
(e) a variable that is the function result of that procedure becomes undefined except for any of its
nonpointer default-initialized subcomponents.
pointer becomes undefined.(17) When a DO CONCURRENT construct terminates, a variable that is defined or becomes undefined
during more than one iteration of the construct becomes undefined.(18) When execution of an iteration of a DO CONCURRENT construct completes, a construct entity of
that construct which has LOCAL or LOCAL_INIT locality becomes undefined.(19) Execution of an asynchronous READ statement causes all of the variables specified by the input list or
SIZE= specifier to become undefined. Execution of an asynchronous namelist READ statement causes(20) When a variable with the TARGET attribute is deallocated, a variable of type C_PTR from theany variable in the namelist group to become undefined if that variable will subsequently be defined
during the execution of the READ statement or the corresponding wait operation (12.7.1).
intrinsic module ISO_C_BINDING becomes undefined if its value is the C address of any part of the(21) When a pointer is deallocated, a variable of type C_PTR from the intrinsic module ISO_C_BINDINGvariable that is deallocated.
becomes undefined if its value is the C address of any part of the target that is deallocated.(22) Execution of the allocation transfer procedure (16.9.137) where the argument TO does not have the
TARGET attribute causes a variable of type C_PTR from the intrinsic module ISO_C_BINDING to(23) When a BLOCK construct completes execution,become undefined if its value is the C address of any part of the argument FROM.
• its unsaved local variables become undefined, and(24) When execution of the host instance of the target of a variable of type C_FUNPTR from the intrinsic• a variable of type C_PTR from the intrinsic module ISO_C_BINDING, whose value is the C
address of an unsaved local variable of the BLOCK construct, becomes undefined.
module ISO_C_BINDING is completed by execution of a RETURN or END statement, the variable(25) Execution of an intrinsic assignment of the type C_PTR or C_FUNPTR from the intrinsic modulebecomes undefined.
ISO_C_BINDING, or of the type TEAM_TYPE from the intrinsic module ISO_FORTRAN_ENV,⃝in which the variable and expr are not on the same image, causes the variable to become undefined.
c ISO/IEC 2017 – All rights reserved 527
ISO/IEC DIS 1539-1:2017 (E)1 Some variables are prohibited from appearing in a syntactic context that would imply definition or undefinition(26) An object with the VOLATILE attribute (8.5.19) might become undefined by means not specified by
the program.
(27) When a pointer becomes associated with a target that is undefined, the pointer becomes undefined.
(28) When an image fails during execution of a segment, a data object on a nonfailed image becomes
undefined if it is not a lock variable and it might become undefined by execution of a statement of
the segment other than an invocation of an atomic subroutine with the object as an actual argument
corresponding to the ATOM dummy argument.
NOTE 19.12
Execution of a defined assignment statement could leave all or part of the variable undefined.
19.6.7 Variable definition context
of the variable (8.5.10, 8.5.15, 15.7). The following are the contexts in which the appearance of a variable implies2 If a reference to a function appears in a variable definition context the result of the function reference shall be asuch definition or undefinition of the variable:
(1) the variable of an assignment-stmt;
(2) a do-variable in a do-stmt or io-implied-do;
(3) an input-item in a read-stmt;
(4) a variable-name in a namelist-stmt if the namelist-group-name appears in a NML= specifier in a
read-stmt;
(5) an internal-file-variable in a write-stmt;
(6) a SIZE= or IOMSG= specifier in an input/output statement;
(7) a specifier in an INQUIRE statement other than FILE=, ID=, and UNIT=;
(8) a NEWUNIT= specifier in an OPEN statement;
(9) a stat-variable, allocate-object, or errmsg-variable;
(10) an actual argument in a reference to a procedure with an explicit interface if the corresponding
dummy argument is not a pointer and has INTENT (OUT) or INTENT (INOUT);
(11) a variable that is a selector in an ASSOCIATE, CHANGE TEAM, SELECT RANK, or SELECT
TYPE construct if the corresponding associate name or any subobject thereof appears in a variable
definition context;
(12) an event-variable in an EVENT POST or EVENT WAIT statement;
(13) a lock-variable in a LOCK or UNLOCK statement;
(14) a scalar-logical-variable in an ACQUIRED_LOCK= specifier;
(15) a team-variable in a FORM TEAM statement.
pointer that is associated with a definable target. That target is the variable that becomes defined or undefined.1 Some pointers are prohibited from appearing in a syntactic context that would imply alteration of the pointer19.6.8 Pointer association context
association status (<IP_ADDRESS>, 8.5.10, 8.5.15, 15.7). The following are the contexts in which the appearance of a⃝pointer implies such alteration of its pointer association status:
528 ⃝
c ISO/IEC 2017 – All rights reserved
ISO/IEC DIS 1539-1:2017 (E)
• a pointer-object in a nullify-stmt;
• a data-pointer-object or proc-pointer-object in a pointer-assignment-stmt;
• an allocate-object in an allocate-stmt or deallocate-stmt;
• an actual argument in a reference to a procedure if the corresponding dummy argument is a pointer with
the INTENT (OUT) or INTENT (INOUT) attribute.
c ISO/IEC 2017 – All rights reserved 529
ISO/IEC DIS 1539-1:2017 (E)
(Blank page)
530 c ISO/IEC 2017 – All rights reservedProcessor dependencies
ISO/IEC DIS 1539-1:2017 (E)
Annex A
(Informative)
A.1 Unspecified items 1 This document does not specify the following: • the properties excluded in 1;• a processor’s error detection capabilities beyond those listed in 4.2;
• which additional intrinsic procedures or modules a processor provides (4.2);
• the number and kind of companion processors (5.5.7);
• the number of representation methods and associated kind type parameter values of the intrinsic types
(7.4), except that there shall be at least two representation methods for type real, and a representation
method of type complex that corresponds to each representation method for type real.
A.2 Processor dependencies 1 According to this document, the following are processor dependent: • the order of evaluation of the specification expressions within the specification part of an invoked Fortran⃝procedure (5.3.5);
• how soon an image terminates if another image initiates error termination (5.3.5);
• the value of a reference to to a coindexed object on a failed image (5.3.6);
• the conditions that cause an image to fail (5.3.6);
• whether the processor supports a concept of process exit status, and if so, the process exit status on program
termination (5.3.7);
• the mechanism of a companion processor, and the means of selecting between multiple companion processors
(5.5.7);
• the processor character set (6.1);
• the means for specifying the source form of a program unit (6.3);
• the maximum number of characters allowed on a source line containing characters not of default kind (6.3.2,
6.3.3);
• the maximum depth of nesting of include lines (6.4);
• the interpretation of the char-literal-constant in the include line (6.4);
• the set of values supported by an intrinsic type, other than logical (7.1.3);
• the kind type parameter value of a complex literal constant, if both the real part and imaginary part are of
type real with the same precision, but have different kind type parameter values (<IP_ADDRESS>);
• the kind of a character length type parameter (<IP_ADDRESS>);
• the blank padding character for nondefault character kind (<IP_ADDRESS>)
c ISO/IEC 2017 – All rights reserved 531
ISO/IEC DIS 1539-1:2017 (E)
• whether particular control characters can appear within a character literal constant in fixed source form(<IP_ADDRESS>);
• the collating sequence for each character set (<IP_ADDRESS>);
• the order of finalization of components of objects of derived type (<IP_ADDRESS>);
• the order of finalization when several objects are finalized as the consequence of a single event (<IP_ADDRESS>);
• whether and when an object is finalized if it is allocated by pointer allocation and it later becomes un-
reachable due to all pointers associated with the object having their pointer association status changed
(<IP_ADDRESS>);
• whether an object is finalized by a deallocation in which an error condition occurs (<IP_ADDRESS>);
• the kind type parameter of each enumeration and its enumerators (7.6);
• whether an array is contiguous, except as specified in 8.5.7;
• the set of error conditions that can occur in ALLOCATE and DEALLOCATE statements (9.7.1, 9.7.3);
• the allocation status of a variable after evaluation of an expression if the evaluation of a function would
change the allocation status of the variable and if a reference to the function appears in the expression in
which the value of the function is not needed to determine the value of the expression (<IP_ADDRESS>);
• the order of deallocation when several objects are deallocated by a DEALLOCATE statement (9.7.3);
• the order of deallocation when several objects are deallocated due to the occurence of an event described
in <IP_ADDRESS>;
• whether an allocated allocatable subobject is deallocated when an error condition occurs in the deallocation
of an object (<IP_ADDRESS>);
• the positive integer values assigned to the stat-variable in a STAT= specifier as the result of an error
condition (9.7.4, 11.6.11);
• the allocation status or pointer association status of an allocate-object if an error condition occurs during
execution of an ALLOCATE or DEALLOCATE statement (9.7.4);
• the value assigned to the errmsg-variable in an ERRMSG= specifier as the result of an error condition
(9.7.5, 11.6.11);
• the kind type parameter value of the result of a numeric intrinsic binary operation where
– both operands are of type integer but with different kind type parameters, and the decimal exponent
ranges are the same,
– one operand is of type real or complex and the other is of type real or complex with a different kind
type parameter, and the decimal precisions are the same,
and for a logical intrinsic binary operation where the operands have different kind type parameters (<IP_ADDRESS>);
• the character assigned to the variable in an intrinsic assignment statement if the kind of the expression is
different and the character is not representable in the kind of the variable (<IP_ADDRESS>);
• the order of evaluation of the specification expressions within the specification part of a BLOCK construct
when the construct is executed (11.1.4);
• the pointer association status of a pointer that has its pointer association changed in more than one iteration
of a DO CONCURRENT construct, on termination of the construct (11.1.7);
• the ordering between records written by different iterations of a DO CONCURRENT construct if the records
are written to a file connected for sequential access by more than one iteration (11.1.7);
• the manner in which the stop code of a STOP or ERROR STOP statement is made available (11.4);
• the mechanisms available for creating dependencies for cooperative synchronization (11.6.5);
532 ⃝c ISO/IEC 2017 – All rights reserved
ISO/IEC DIS 1539-1:2017 (E)• the value of the count of the event variable in an EVENT POST or EVENT WAIT statement if an error
condition occurs (11.6.7, 11.6.8);• the image index value established for each image in a team by a FORM TEAM statement without a
NEW_INDEX= specifier (11.6.9);• the set of error conditions that can occur in image control statements (11.6.11);
• the relationship between the file storage units when viewing a file as a stream file, and the records when
viewing that file as a record file (12);• whether particular control characters can appear in a formatted record or a formatted stream file (12.2.2);
• the form of values in an unformatted record (12.2.3);
• at any time, the set of allowed access methods, set of allowed forms, set of allowed actions, and set of
allowed record lengths for a file (12.3);• the set of allowable names for a file (12.3);
• whether a named file on one image is the same as a file with the same name on another image (12.3.1);
• the set of external files that exist for a program (12.3.2);
• the relationship between positions of successive file storage units in an external file that is connected for
formatted stream access (<IP_ADDRESS>);• the external unit preconnected for sequential formatted input and identified by an asterisk or the named
constant INPUT_UNIT of the ISO_FORTRAN_ENV intrinsic module (12.5);• the external unit preconnected for sequential formatted output and identified by an asterisk or the named
constant OUTPUT_UNIT of the ISO_FORTRAN_ENV intrinsic module (12.5);• the external unit preconnected for sequential formatted output and identified by the named constant ER-
ROR_UNIT of the ISO_FORTRAN_ENV intrinsic module, and whether this unit is the same as OUT-• at any time, the set of external units that exist for an image (12.5.3);PUT_UNIT (12.5);
• whether a unit can be connected to a file that is also connected to a C stream (12.5.4);
• whether a file can be connected to more than one unit at the same time (12.5.4);
• the effect of performing input/output operations on multiple units while they are connected to the same
external file (12.5.4);• the result of performing input/output operations on a unit connected to a file that is also connected to a C
stream (12.5.4);• whether the files connected to the units INPUT_UNIT, OUTPUT_UNIT, and ERROR_UNIT correspond
to the predefined C text streams standard input, standard output, and standard error, respectively (12.5.4);• the results of performing input/output operations on an external file both from Fortran and from a procedure
defined by means other than Fortran (12.5.4);• the default value for the ACTION= specifier in an OPEN statement (<IP_ADDRESS>);
• the encoding of a file opened with ENCODING=’DEFAULT’ (<IP_ADDRESS>);
• the file connected by an OPEN statement with STATUS=’SCRATCH’ (<IP_ADDRESS>);
• the interpretation of case in a file name (<IP_ADDRESS>, <IP_ADDRESS>);
• the position of a file after executing an OPEN statement with a POSITION= specifier of ASIS, when the
file previously existed but was not connected (<IP_ADDRESS>);• the default value for the RECL= specifier in an OPEN statement (<IP_ADDRESS>);
• the effect of RECL= on a record containing any nondefault characters (<IP_ADDRESS>);
⃝
c ISO/IEC 2017 – All rights reserved 533
ISO/IEC DIS 1539-1:2017 (E)
• the default input/output rounding mode (<IP_ADDRESS>);• the default sign mode (<IP_ADDRESS>);
• the file status when STATUS=’UNKNOWN’ is specified in an OPEN statement (<IP_ADDRESS>);
• the value assigned to the variable in the ID= specifier in an asynchronous data transfer statement when
execution of the statement is successfully completed (<IP_ADDRESS>);
• whether POS= is permitted with particular files, and whether POS= can position a particular file to a
position prior to its current position (<IP_ADDRESS>);
• the form in which a single value of derived type is treated in an unformatted input/output statement if the
effective item is not processed by a defined input/output procedure (12.6.3);
• the result of unformatted input when the value stored in the file has a different type or type parameters
from that of the input list item (<IP_ADDRESS>.2);
• the negative value of the unit argument to a defined input/output procedure if the parent data transfer
statement accesses an internal file (<IP_ADDRESS>.2);
• the manner in which the processor makes the value of the iomsg argument of a defined input/output
procedure available if the procedure assigns a nonzero value to the iostat argument and the processor
therefore terminates execution of the program (<IP_ADDRESS>.2);
• the action caused by the flush operation, whether the processor supports the flush operation for the specified
unit, and the negative value assigned to the IOSTAT= variable if the processor does not support the flush
operation for the specified unit (12.9);
• the case of characters assigned to the variable in a NAME= specifier in an INQUIRE statement (<IP_ADDRESS>);
• which of the connected external unit numbers is assigned to the scalar-int-variable in the NUMBER=
specifier in an INQUIRE by file statement, if more than one unit on an image is connected to the file
(<IP_ADDRESS>);
• the value of the variable in a POSITION= specifier in an INQUIRE statement if the file has been repositioned
since connection (<IP_ADDRESS>);
• the relationship between file size and the data stored in records in a sequential or direct access file
(<IP_ADDRESS>);
• the number of file storage units needed to store data in an unformatted file (12.10.3);
• the set of error conditions that can occur in input/output statements (12.11.1);
• when an input/output error condition occurs or is detected (12.11.1);
• the positive integer value assigned to the variable in an IOSTAT= specifier as the result of an error condition
(12.11.5);
• the value assigned to the variable in an IOMSG= specifier as the result of an error condition (12.11.6);
• the result of output of non-representable characters to a Unicode file (13.7.1);
• the interpretation of the optional non-blank characters within the parentheses of a real NaN input field
(<IP_ADDRESS>.2);
• the interpretation of a sign in a NaN input field (<IP_ADDRESS>.2);
• for output of an IEEE NaN, whether after the letters ’NaN’, the processor produces additional alphanumeric
characters enclosed in parentheses (<IP_ADDRESS>.2);
• the choice of binary exponent in EX output editing (<IP_ADDRESS>.6);
• the effect of the input/output rounding mode PROCESSOR_DEFINED (<IP_ADDRESS>.8);
• which value is chosen if the input/output rounding mode is NEAREST and the value to be converted is
exactly halfway between the two nearest representable values in the result format (<IP_ADDRESS>.8);
534 ⃝c ISO/IEC 2017 – All rights reserved
ISO/IEC DIS 1539-1:2017 (E)• the field width, decimal part width, and exponent width used for the G0 edit descriptor (13.7.5);
• the file position when position editing skips a character of nondefault kind in an internal file of default
character kind or an external unit that is not connected to a Unicode file (<IP_ADDRESS>);• when the sign mode is PROCESSOR_DEFINED, whether a plus sign appears in a numeric output field
for a nonnegative value (13.8.4);• the results of list-directed output (13.10.4);
• the results of namelist output (13.11.4);
• the interaction between argument association and pointer association, (<IP_ADDRESS>);
• the values returned by some intrinsic functions (16);
• how the sequences of atomic actions in unordered segments interleave (16.5);
• the value assigned to a STAT argument in a reference to an atomic subroutine when an error condition
occurs (16.5);• the effect of calling EXECUTE_COMMAND_LINE on any image other than image 1 in the initial team
(16.7);• whether each image uses a separate random number generator, or if some or all images use common random
number generators (16.7);• whether the results returned from CPU_TIME, DATE_AND_TIME and SYSTEM_CLOCK are depend-
ent on which image calls them (16.7);• the set of error conditions that can occur in some intrinsic subroutines (16.9);
• the value assigned to a CMDSTAT, ERRMSG, EXITSTAT, STAT, or STATUS argument to indicate a
processor-dependent error condition (16.9);• the computed value of the the intrinsic subroutine CO_REDUCE (16.9.49) and the intrinsic subroutine
CO_SUM (16.9.50);• the value assigned to the TIME argument by the intrinsic subroutine CPU_TIME (16.9.57);
• whether date, clock, and time zone information is available (16.9.59);
• whether date, clock, and time zone information on one image is the same as that on another image (16.9.59);
• the value of command argument zero, if the processor does not support the concept of a command name
(16.9.83);• the order of command arguments (16.9.83);
• whether the significant length of a command argument includes trailing blanks (16.9.83);
• the interpretation of case for the NAME argument of the intrinsic subroutine GET_ENVIRONMENT_-
VARIABLE (16.9.84);• whether an environment variable that exists on an image also exists on another image, and if it does exist
on both images, whether the values are the same or different (16.9.84);• the value assigned to the pseudorandom number generator by the intrinsic subroutine RANDOM_INIT
(16.9.155);• the computation of the seed value used by the pseudorandom number generator (16.9.157);
• on images that use a common random number generator, the interleaving of values assigned by RANDOM_-
NUMBER in unordered segments(16.7);• the value assigned to the seed by the intrinsic subroutine RANDOM_SEED when no argument is present
(16.9.157);• the values assigned to its arguments by the intrinsic subroutine SYSTEM_CLOCK (16.9.186);
⃝
c ISO/IEC 2017 – All rights reserved 535
ISO/IEC DIS 1539-1:2017 (E)
• the values of the named constants in the intrinsic module ISO_FORTRAN_ENV (16.10.2);• the values returned by the functions COMPILER_OPTIONS and COMPILER_VERSION in the intrinsic
module ISO_FORTRAN_ENV (16.10.2);
• the extent to which a processor supports IEEE arithmetic (17);
• whether a flag that is quiet on entry to a scoping unit that does not access IEEE_FEATURES, IEEE_-
EXCEPTIONS, or IEEE_ARITHMETIC is signaling on exit (17.1);
• the conditions under which IEEE_OVERFLOW is raised in a calculation involving non-ISO/IEC/IEEE
60559:2011 floating-point data (17.3);
• the conditions under which IEEE_OVERFLOW and IEEE_DIVIDE_BY_ZERO are raised in a floating-
point exponentiation operation (17.3);
• the conditions under which IEEE_DIVIDE_BY_ZERO is raised in a calculation involving floating-point
data that do not conform to ISO/IEC/IEEE 60559:2011 (17.3);
• whether an exception signals at the end of a sequence of statements that has no invocations of IEEE_GET_-
FLAG, IEEE_SET_FLAG, IEEE_GET_STATUS, IEEE_SET_STATUS, or IEEE_SET_HALTING_-
MODE, in which execution of an operation would cause it to signal, if no value of a variable depends upon
the result of the operation (17.3);
• the initial rounding modes (17.4);
• whether the processor supports a particular rounding mode (17.4);
• the effect of the rounding mode IEEE_OTHER, if supported (17.4);
• the initial underflow mode (17.5);
• the initial halting mode (17.6);
• whether IEEE_INT implements the convertToInteger{round} or convertToIntegerExact{round} operation
specified by ISO/IEC/IEEE 60559:2011 (17.11.11);
• which argument is the result value of IEEE_MAX_NUM, IEEE_MAX_NUM_MAG, IEEE_MIN_NUM,
or IEEE_MIN_NUM_MAG when both arguments are quiet NaNs or are zeros (17.11.17, 17.11.18, 17.11.19,
17.11.20);
• the requirements on the storage sequence to be associated with the pointer FPTR by the C_F_POINTER
subroutine (<IP_ADDRESS>);
• the order of the members of the CFI_dim_t structure defined in the source file CFI_Fortran_binding.h
(18.5.2);
• members of the CFI_cdesc_t structure defined in the source file CFI_Fortran_binding.h beyond the re-
quirements of 18.5.3;
• the value of CFI_MAX_RANK in the source file CFI_Fortran_binding.h (18.5.4);
• the value of CFI_VERSION in the source file CFI_Fortran_binding.h (18.5.4);
• which error condition is detected if more than one error condition could be detected for an invocation of
one of the functions declared in the source file CFI_Fortran_binding.h (<IP_ADDRESS>);
• the values of the attribute specifier macros defined in the source file CFI_Fortran_binding.h (18.5.4);
• the values of the type specifier macros defined in the source file CFI_Fortran_binding.h;
• which additional type specifier values are defined in the source file CFI_Fortran_binding.h (18.5.4);
• the values of the error code macros other than CFI_SUCCESS that are defined in the source file CFI_-
Fortran_binding.h (18.5.4);
• the base address of a zero-sized array (18.5.3);
• the values of the floating-point exception flags on entry to a procedure defined by means other than Fortran
536 c ISO/IEC 2017 – All rights reserved(18.10.3);
ISO/IEC DIS 1539-1:2017 (E)
• whether a procedure defined by means other than Fortran is an asynchronous communication initiation or
completion procedure (18.10.4).⃝
c ISO/IEC 2017 – All rights reserved 537
ISO/IEC DIS 1539-1:2017 (E)
(Blank page)
1 The obsolescent features are those features of Fortran 90 that were redundant and for which better methods were
538 c ISO/IEC 2017 – All rights reservedDeleted and obsolescent features
ISO/IEC DIS 1539-1:2017 (E)
Annex B
(Informative)
B.1 Deleted features from Fortran 90 1 These deleted features are those features of Fortran 90 that were redundant and considered largely unused. 2 The following Fortran 90 features are not required. (1) Real and double precision DO variables.3 See ISO/IEC 1539:1991 for detailed rules of how these deleted features worked.In Fortran 77 and Fortran 90, a DO variable was allowed to be of type real or double precision
in addition to type integer; this has been deleted. A similar result can be achieved by using a DO
construct with no loop control and the appropriate exit test.
(2) Branching to an END IF statement from outside its block.
In Fortran 77 and Fortran 90, it was possible to branch to an END IF statement from outside the
IF construct; this has been deleted. A similar result can be achieved by branching to a CONTINUE
statement that is immediately after the END IF statement.
(3) PAUSE statement.
The PAUSE statement, provided in Fortran 66, Fortran 77, and Fortran 90, has been deleted.
A similar result can be achieved by writing a message to the appropriate unit, followed by reading
from the appropriate unit.
(4) ASSIGN and assigned GO TO statements, and assigned format specifiers.
The ASSIGN statement and the related assigned GO TO statement, provided in Fortran 66,
Fortran 77, and Fortran 90, have been deleted. Further, the ability to use an assigned integer as a
format, provided in Fortran 77 and Fortran 90, has been deleted. A similar result can be achieved
by using other control constructs instead of the assigned GO TO statement and by using a default
character variable to hold a format specification instead of using an assigned integer.
(5) H edit descriptor.
In Fortran 77 and Fortran 90, there was an alternative form of character string edit descriptor,
which had been the only such form in Fortran 66; this has been deleted. A similar result can be
achieved by using a character string edit descriptor.
(6) Vertical format control.
In Fortran 66, Fortran 77, Fortran 90, and Fortran 95 formatted output to certain units resulted
in the first character of each record being interpreted as controlling vertical spacing. There was no
standard way to detect whether output to a unit resulted in this vertical format control, and no
way to specify that it should be applied; this has been deleted. The effect can be achieved by
post-processing a formatted file.
⃝c ISO/IEC 2017 – All rights reserved 5391 These deleted features are those features of Fortran 2008 that were redundant and considered largely unused.
ISO/IEC DIS 1539-1:2017 (E)
B.2 Deleted features from Fortran 2008
2 The following Fortran 2008 features are not required. (1) Arithmetic IF statement.The arithmetic IF statement is incompatible with ISO/IEC/IEEE 60559:2011 and necessarily involves
the use of statement labels; statement labels can hinder optimization, and make code hard to read
and maintain. Similar logic can be more clearly encoded using other conditional statements.
(2) Nonblock DO construct
The nonblock forms of the DO loop were confusing and hard to maintain. Shared termination and
dual use of labeled action statements as do termination and branch targets were especially error-
prone.
B.3 Obsolescent features B.3.1 General
available in Fortran 90. Subclause 4.4.3 describes the nature of the obsolescent features. The obsolescent features1 An alternate return introduces labels into an argument list to allow the called procedure to direct the executionin this document are the following.
(1) Alternate return — see B.3.2.
(2) Computed GO TO — see B.3.3.
(3) Statement functions — see B.3.4.
(4) DATA statements amongst executable statements — see B.3.5.
(5) Assumed length character functions — see B.3.6.
(6) Fixed form source — see B.3.7.
(7) CHARACTER* form of CHARACTER declaration — see B.3.8.
(8) ENTRY statements — see B.3.9.
(9) Label form of DO statement – see B.3.10.
(10) COMMON and EQUIVALENCE statements, and the block data program unit – see B.3.11.
(11) Specific names for intrinsic functions – see B.3.12.
(12) FORALL construct and statement – see B.3.13
B.3.2 Alternate return
of the caller upon return. The same effect can be achieved with a return code that is used in a SELECT CASEconstruct on return. This avoids an irregularity in the syntax and semantics of argument association. For example,
CALL SUBR_NAME (X, Y, Z, *100, *200, *300)
can be replaced by
CALL SUBR_NAME (X, Y, Z, RETURN_CODE)
SELECT CASE (RETURN_CODE)
540 ⃝c ISO/IEC 2017 – All rights reserved
ISO/IEC DIS 1539-1:2017 (E)
CASE (1)
...
CASE (2)
...
CASE (3)
...
CASE DEFAULT
...
END SELECT
B.3.3 Computed GO TO statement 1 The computed GO TO statement has been superseded by the SELECT CASE construct, which is a generalized,
easier to use, and clearer means of expressing the same computation.1 Statement functions are subject to a number of nonintuitive restrictions and are a potential source of error becauseB.3.4 Statement functions
their syntax is easily confused with that of an assignment statement.2 The internal function is a more generalized form of the statement function and completely supersedes it.
B.3.5 DATA statements among executables1 The statement ordering rules allow DATA statements to appear anywhere in a program unit after the specific-
ation statements. The ability to position DATA statements amongst executable statements is very rarely used,1 Assumed character length for functions is an irregularity in the language in that elsewhere in Fortran the philo-unnecessary, and a potential source of error.
B.3.6 Assumed character length functions
sophy is that the attributes of a function result depend only on the actual arguments of the invocation and on2 Note that dummy arguments of a function can have assumed character length.any data accessible by the function through host or use association. Some uses of this facility can be replaced
with an automatic character length function, where the length of the function result is declared in a specification
expression. Other uses can be replaced by the use of a subroutine whose arguments correspond to the function
result and the function arguments.
B.3.7 Fixed form source1 Fixed form source was designed when the principal machine-readable input medium for new programs was punched
cards. Now that new and amended programs are generally entered via keyboards with screen displays, it is an2 It is a simple matter for a software tool to convert from fixed to free form source.unnecessary overhead, and is potentially error-prone, to have to locate positions 6, 7, or 72 on a line. Free form
source was designed expressly for this more modern technology.
⃝c ISO/IEC 2017 – All rights reserved 5411 In addition to the CHARACTER*char-length form introduced in Fortran 77, Fortran 90 provided the CHAR-
ISO/IEC DIS 1539-1:2017 (E)
B.3.8 CHARACTER* form of CHARACTER declaration
ACTER([ LEN = ] type-param-value) form. The older form (CHARACTER*char-length) is redundant.1 ENTRY statements allow more than one entry point to a subprogram, facilitating sharing of data items andB.3.9 ENTRY statements
executable statements local to that subprogram.2 This can be replaced by a module containing the (private) data items, with a module procedure for each entry
point and the shared code in a private module procedure.1 The label in the DO statement is redundant with the construct name. Furthermore, the label allows unrestrictedB.3.10 Label DO statement
branches and, for its main purpose (the target of a conditional branch to skip the rest of the current iteration),1 Common blocks are error-prone and have largely been superseded by modules. EQUIVALENCE similarly isis redundant with the CYCLE statement, which is clearer.
B.3.11 COMMON and EQUIVALENCE statements and the block data program unit
error-prone. Whilst use of these statements was invaluable prior to Fortran 90 they are now redundant and1 The specific names of the intrinsic functions are often obscure and hinder portability. They have been redundantcan inhibit performance. The block data program unit exists only to serve common blocks and hence is also
redundant.
B.3.12 Specific names for intrinsic functions
since Fortran 90. Use generic names for references to intrinsic procedures.1 The FORALL construct and statement were added to the language in the expectation that they would enableB.3.13 FORALL construct and statement
highly efficient execution, especially on parallel processors. However, experience indicates that they are too1 The following features were new in Fortran 2008 but not originally listed in its Introduction as being new features:complex and have too many restrictions for compilers to take advantage of them. They are redundant with the
DO CONCURRENT construct, and many of the manipulations for which they might be used can be done more
effectively using pointers, especially using pointer rank remapping.
542 ⃝
c ISO/IEC 2017 – All rights reserved
ISO/IEC DIS 1539-1:2017 (E)
Annex C
(Informative)
Extended notes
C.1 Fortran 2008 features not mentioned in its Introduction
• An array or object with a nonconstant length type parameter can have the VALUE attribute.2 All but the last two of the above list were subsequently added to the Introduction by Technical Corrigenda.• Multiple allocations are permitted in a single ALLOCATE statement with the SOURCE= specifier.
• A PROCEDURE statement can have a double colon before the first procedure name.
• An argument to a pure procedure can have default INTENT if it has the VALUE attribute.
• The PROTECTED attribute can be specified by the procedure declaration statement.
• A defined-operator can be used in a specification expression.
• All transformational functions from the intrinsic modules IEEE_ARITHMETIC and IEEE_EXCEPTIONS
can be used in constant expressions. All transformational functions from the intrinsic modules IEEE_-
ARITHMETIC, IEEE_EXCEPTIONS, and ISO_C_BINDING can be used in specification expressions.
• A contiguous array variable that is not interoperable but which has interoperable type and kind type
parameter (if any), and a scalar character variable with length greater than 1 and kind C_CHAR in the
intrinsic module ISO_C_BINDING, can be used as the argument of the function C_LOC in the intrinsic
module ISO_C_BINDING, provided the variable has the POINTER or TARGET attribute.
• The name of an external procedure that has a binding label is a local identifier and not a global identifier.
• A procedure that is not a procedure pointer can be an actual argument that corresponds to a procedure
pointer dummy argument with the INTENT (IN) attribute.
• An interface body for an external procedure that does not exist in a program can be used to specify an
explicit specific interface.
C.2 Clause 7 notes1 One can select the real approximation method for an entire program through the use of a module and theC.2.1 Selection of the approximation methods (<IP_ADDRESS>)
parameterized real type. This is accomplished by defining a named integer constant to have a particular kind2 To avoid the use of the processor-dependent values 4 or 8, replace 8 by KIND (0.0) or KIND (0.0D0). Anothertype parameter value and using that named constant in all real, complex, and derived-type declarations. For
example, the specification statements
INTEGER, PARAMETER :: LONG_FLOAT = 8
REAL (LONG_FLOAT) X, Y
COMPLEX (LONG_FLOAT) Z
⃝c ISO/IEC 2017 – All rights reserved 543
ISO/IEC DIS 1539-1:2017 (E)
specify that the approximation method corresponding to a kind type parameter value of 8 is supplied for the data
objects X, Y, and Z in the program unit. The kind type parameter value LONG_FLOAT can be made available
to an entire program by placing the INTEGER specification statement in a module and accessing the named
constant LONG_FLOAT with a USE statement. Note that by changing 8 to 4 once in the module, a different
approximation method is selected.
way to avoid these processor-dependent values is to select the kind value using the intrinsic function SELEC-3 As kind values have no portable meaning, a good practice is to use them in programs only through namedTED_REAL_KIND (16.9.170). In the above specification statement, the 8 might be replaced by, for instance,
SELECTED_REAL_KIND (10, 50), which requires an approximation method to be selected with at least 10
decimal digits of precision and a range from 10−50 to 1050 . There are no magnitude or ordering constraints placed
on kind values, in order that implementers have flexibility in assigning such values and can add new kinds without
changing previously assigned kind values.
constants as described above (for example, SINGLE, IEEE_SINGLE, DOUBLE, and QUAD), rather than using1 The default accessibility of the components of an extended type can be specified in the type definition. Thethe kind values directly.
C.2.2 Type extension and component accessibility (<IP_ADDRESS>, 7.5.4)
accessibility of its components can be specified individually. For example:1 The only difference between this example and the same thing rewritten to use generic interface blocks is thatmodule types
type base_type
private !-- Sets default accessibility
integer :: i !-- a private component
integer, private :: j !-- another private component
integer, public :: k !-- a public component
end type base_type
type, extends(base_type) :: my_type
private !-- Sets default for components declared in my_type
integer :: l !-- A private component.
integer, public :: m !-- A public component.
end type my_type
end module types
subroutine sub
use types
type (my_type) :: x
...
call another_sub( &
x%base_type, & !-- ok because base_type is a public subobject of x
x%base_type%k, & !-- ok because x%base_type is ok and has k as a
544 ⃝
c ISO/IEC 2017 – All rights reserved
ISO/IEC DIS 1539-1:2017 (E)
!-- public component.
x%k, & !-- ok because it is shorthand for x%base_type%k
x%base_type%i, & !-- Invalid because i is private.
x%i) !-- Invalid because it is shorthand for x%base_type%i
end subroutine sub
C.2.3 Generic type-bound procedures (7.5.5)
Example of a derived type with generic type-bound procedures:
with type-bound procedures,USE rational_numbers, ONLY: rational
does not block the type-bound procedures; the user still gets access to the defined assignment and extended
operations.
MODULE rational_numbers
IMPLICIT NONE
PRIVATE
TYPE,PUBLIC :: rational
PRIVATE
INTEGER n,d
CONTAINS
! ordinary type-bound procedure
PROCEDURE :: real => rat_to_real
! specific type-bound procedures for generic support
PROCEDURE,PRIVATE :: rat_asgn_i, rat_plus_i, rat_plus_rat => rat_plus
PROCEDURE,PRIVATE,PASS(b) :: i_plus_rat
! generic type-bound procedures
GENERIC :: ASSIGNMENT(=) => rat_asgn_i
GENERIC :: OPERATOR(+) => rat_plus_rat, rat_plus_i, i_plus_rat
END TYPE
CONTAINS
ELEMENTAL REAL FUNCTION rat_to_real(this) RESULT(r)
CLASS(rational),INTENT(IN) :: thisr = REAL(this%n)/this%d
END FUNCTION
ELEMENTAL SUBROUTINE rat_asgn_i(a,b)
CLASS(rational),INTENT(OUT) :: aINTEGER,INTENT(IN) :: b
a%n = b
a%d = 1
END SUBROUTINE
ELEMENTAL TYPE(rational) FUNCTION rat_plus_i(a,b) RESULT(r)
CLASS(rational),INTENT(IN) :: aINTEGER,INTENT(IN) :: b
⃝c ISO/IEC 2017 – All rights reserved 545
ISO/IEC DIS 1539-1:2017 (E)
r%n = a%n + b*a%dr%d = a%d
END FUNCTION
ELEMENTAL TYPE(rational) FUNCTION i_plus_rat(a,b) RESULT(r)
INTEGER,INTENT(IN) :: aCLASS(rational),INTENT(IN) :: b
r%n = b%n + a*b%d
r%d = b%d
END FUNCTION
ELEMENTAL TYPE(rational) FUNCTION rat_plus(a,b) RESULT(r)
CLASS(rational),INTENT(IN) :: a,br%n = a%n*b%d + b%n*a%d
r%d = a%d*b%d
END FUNCTION
END
C.2.4 Abstract types (<IP_ADDRESS>) 1 The following illustrates how an abstract type can be used as the basis for a collection of related types, and how
a non-abstract member of that collection can be created by type extension.TYPE, ABSTRACT :: DRAWABLE_OBJECT
REAL, DIMENSION(3) :: RGB_COLOR = (/1.0,1.0,1.0/) ! White
REAL, DIMENSION(2) :: POSITION = (/0.0,0.0/) ! Centroid
CONTAINS
PROCEDURE(RENDER_X), PASS(OBJECT), DEFERRED :: RENDER
END TYPE DRAWABLE_OBJECT
ABSTRACT INTERFACE
SUBROUTINE RENDER_X(OBJECT, WINDOW)
IMPORT DRAWABLE_OBJECT, X_WINDOWCLASS(DRAWABLE_OBJECT), INTENT(IN) :: OBJECT
CLASS(X_WINDOW), INTENT(INOUT) :: WINDOW
END SUBROUTINE RENDER_X
END INTERFACE
...
TYPE, EXTENDS(DRAWABLE_OBJECT) :: DRAWABLE_TRIANGLE ! Not ABSTRACT
REAL, DIMENSION(2,3) :: VERTICES ! In relation to centroid
CONTAINS
PROCEDURE, PASS(OBJECT) :: RENDER=>RENDER_TRIANGLE_X
END TYPE DRAWABLE_TRIANGLE
2 The actual drawing procedure will draw a triangle in WINDOW with vertices at x and y coordinates at
OBJECT%POSITION(1)+OBJECT%VERTICES(1,1:3) and OBJECT%POSITION(2)+OBJECT%VERTICES(2,1:3):546 ⃝c ISO/IEC 2017 – All rights reserved
ISO/IEC DIS 1539-1:2017 (E)
SUBROUTINE RENDER_TRIANGLE_X(OBJECT, WINDOW)
CLASS(DRAWABLE_TRIANGLE), INTENT(IN) :: OBJECT
CLASS(X_WINDOW), INTENT(INOUT) :: WINDOW
...
END SUBROUTINE RENDER_TRIANGLE_X
C.2.5 Structure constructors and generic names (7.5.10) 1 A generic name can be the same as a type name. This can be used to emulate user-defined structure constructors
for that type, even if the type has private components. For example:MODULE mytype_module
TYPE mytype
PRIVATE
COMPLEX value
LOGICAL exact
END TYPE
INTERFACE mytype
MODULE PROCEDURE int_to_mytype
END INTERFACE
! Operator definitions etc.
...
CONTAINS
TYPE(mytype) FUNCTION int_to_mytype(i)
INTEGER,INTENT(IN) :: iint_to_mytype%value = i
int_to_mytype%exact = .TRUE.
END FUNCTION
! Procedures to support operators etc.
...
END
PROGRAM example
USE mytype_moduleTYPE(mytype) x
x = mytype(17)
END
2 The type name can still be used as a generic name if the type has type parameters. For example:
MODULE mTYPE t(kind)
INTEGER, KIND :: kind
COMPLEX(kind) value
END TYPE
INTEGER,PARAMETER :: single = KIND(0.0), double = KIND(0d0)
INTERFACE t
⃝c ISO/IEC 2017 – All rights reserved 547
ISO/IEC DIS 1539-1:2017 (E)
MODULE PROCEDURE real_to_t1, dble_to_t2, int_to_t1, int_to_t2
END INTERFACE
...
CONTAINS
TYPE(t(single)) FUNCTION real_to_t1(x)
REAL(single) xreal_to_t1%value = x
END FUNCTION
TYPE(t(double)) FUNCTION dble_to_t2(x)
REAL(double) xdble_to_t2%value = x
END FUNCTION
TYPE(t(single)) FUNCTION int_to_t1(x,mold)
INTEGER xTYPE(t(single)) mold
int_to_t1%value = x
END FUNCTION
TYPE(t(double)) FUNCTION int_to_t2(x,mold)
INTEGER xTYPE(t(double)) mold
int_to_t2%value = x
END FUNCTION
...
END
PROGRAM example
USE mTYPE(t(single)) x
TYPE(t(double)) y
x = t(1.5) ! References real_to_t1
x = t(17,mold=x) ! References int_to_t1
y = t(1.5d0) ! References dble_to_t2
y = t(42,mold=y) ! References int_to_t2
y = t(kind(0d0)) ((0,1)) ! Uses the structure constructor for type t
END
Example of a parameterized derived type with final subroutines:
C.2.6 Final subroutines (7.5.6, <IP_ADDRESS>, <IP_ADDRESS>, <IP_ADDRESS>)
MODULE mTYPE t(k)
INTEGER, KIND :: k
REAL(k),POINTER :: vector(:) => NULL()
CONTAINS
FINAL :: finalize_t1s, finalize_t1v, finalize_t2e
END TYPE
548 ⃝c ISO/IEC 2017 – All rights reserved
ISO/IEC DIS 1539-1:2017 (E)
CONTAINS
SUBROUTINE finalize_t1s(x)
TYPE(t(KIND(0.0))) xIF (ASSOCIATED(x%vector)) DEALLOCATE(x%vector)
END SUBROUTINE
SUBROUTINE finalize_t1v(x)
TYPE(t(KIND(0.0))) x(:)DO i=LBOUND(x,1),UBOUND(x,1)
IF (ASSOCIATED(x(i)%vector)) DEALLOCATE(x(i)%vector)
END DO
END SUBROUTINE
ELEMENTAL SUBROUTINE finalize_t2e(x)
TYPE(t(KIND(0.0d0))),INTENT(INOUT) :: xIF (ASSOCIATED(x%vector)) DEALLOCATE(x%vector)
END SUBROUTINE
END MODULE
SUBROUTINE example(n)
USE mTYPE(t(KIND(0.0))) a,b(10),c(n,2)
TYPE(t(KIND(0.0d0))) d(n,n)
...
! Returning from this subroutine will effectively do
! CALL finalize_t1s(a)
! CALL finalize_t1v(b)
! CALL finalize_t2e(d)
! No final subroutine will be called for variable C because the user
! omitted to define a suitable specific procedure for it.
END SUBROUTINE
Example of extended types with final subroutines:
MODULE mTYPE t1
REAL a,b
END TYPE
TYPE,EXTENDS(t1) :: t2
REAL,POINTER :: c(:),d(:)
CONTAINS
FINAL :: t2f
END TYPE
TYPE,EXTENDS(t2) :: t3
REAL,POINTER :: e
CONTAINS
FINAL :: t3f
END TYPE
...
⃝
c ISO/IEC 2017 – All rights reserved 549
ISO/IEC DIS 1539-1:2017 (E)
CONTAINS
SUBROUTINE t2f(x) ! Finalizer for TYPE(t2)’s extra components
TYPE(t2) :: xIF (ASSOCIATED(x%c)) DEALLOCATE(x%c)
IF (ASSOCIATED(x%d)) DEALLOCATE(x%d)
END SUBROUTINE
SUBROUTINE t3f(y) ! Finalizer for TYPE(t3)’s extra components
TYPE(t3) :: yIF (ASSOCIATED(y%e)) DEALLOCATE(y%e)
END SUBROUTINE
END MODULE
SUBROUTINE example
USE mTYPE(t1) x1
TYPE(t2) x2
TYPE(t3) x3
...
! Returning from this subroutine will effectively do
! ! Nothing to x1; it is not finalizable
! CALL t2f(x2)
! CALL t3f(x3)
! CALL t2f(x3%t2)
END SUBROUTINE
C.3 Clause 8 notes: The VOLATILE attribute (8.5.19) 1 The following example shows the use of a variable with the VOLATILE attribute to communicate with an
asynchronous process, in this case the operating system. The program detects a user keystroke on the terminal2 The VOLATILE attribute is necessary to prevent an optimizing compiler from storing the communication variableand reacts at a convenient point in its processing.
in a register or from doing flow analysis and deciding that the EXIT statement can never be executed.
SUBROUTINE TERMINATE_ITERATIONS
PRINT *, " Hit any key to terminate iterations!"
LOGICAL, VOLATILE :: USER_HIT_ANY_KEY ! Have the OS start to look for a user keystroke and set the variable ! "USER_HIT_ANY_KEY" to TRUE as soon as it detects a keystroke. ! This call is operating system dependent. CALL OS_BEGIN_DETECT_USER_KEYSTROKE( USER_HIT_ANY_KEY ) USER_HIT_ANY_KEY = .FALSE. ! This will ignore any recent keystrokes. DO I = 1,100
... ! Compute a value for R.
550 c ISO/IEC 2017 – All rights reservedPRINT *, I, R
ISO/IEC DIS 1539-1:2017 (E)
IF (USER_HIT_ANY_KEY) EXIT ENDDO
! Have the OS stop looking for user keystrokes.
CALL OS_STOP_DETECT_USER_KEYSTROKE
END SUBROUTINE TERMINATE_ITERATIONS
C.4 Clause 9 notes C.4.1 Structure components (9.4.2) 1 Components of a structure are referenced by writing the components of successive levels of the structure hierarchy
until the desired component is described. For example,
TYPE ID_NUMBERS
INTEGER SSN
INTEGER EMPLOYEE_NUMBER
END TYPE ID_NUMBERS
TYPE PERSON_ID
CHARACTER (LEN=30) LAST_NAME
CHARACTER (LEN=1) MIDDLE_INITIAL
CHARACTER (LEN=30) FIRST_NAME
TYPE (ID_NUMBERS) NUMBER
END TYPE PERSON_ID
TYPE PERSON
INTEGER AGE
TYPE (PERSON_ID) ID
END TYPE PERSON
TYPE (PERSON) GEORGE, MARY
*, GEORGE % AGE ! Print the AGE component *, MARY % ID % LAST_NAME ! Print LAST_NAME of MARY *, MARY % ID % NUMBER % SSN ! Print SSN of MARY *, GEORGE % ID % NUMBER ! Print SSN and EMPLOYEE_NUMBER of GEORGE 2 A structure component can be a data object of intrinsic type as in the case of GEORGE % AGE or it can be
of derived type as in the case of GEORGE % ID % NUMBER. The resultant component can be a scalar or anarray of intrinsic or derived type.
TYPE LARGE
INTEGER ELT (10)
INTEGER VAL
⃝c ISO/IEC 2017 – All rights reserved 551
ISO/IEC DIS 1539-1:2017 (E)END TYPE LARGE
TYPE (LARGE) A (5) ! 5 element array, each of whose elements ! includes a 10 element array ELT and! a scalar VAL.
PRINT *, A (1) ! Prints 10 element array ELT and scalar VAL. PRINT *, A (1) % ELT (3) ! Prints scalar element 3 ! of array element 1 of A.
PRINT *, A (2:4) % VAL ! Prints scalar VAL for array elements ! 2 to 4 of A.3 Components of an object of extensible type that are inherited from the parent type can be accessed as a whole
by using the parent component name, or individually, either with or without qualifying them by the parentcomponent name. For example:
TYPE POINT ! A base type
REAL :: X, Y
END TYPE POINT
TYPE, EXTENDS(POINT) :: COLOR_POINT ! An extension of TYPE(POINT)
! Components X and Y, and component name POINT, inherited from parentINTEGER :: COLOR
END TYPE COLOR_POINT
TYPE(POINT) :: PV = POINT(1.0, 2.0)
TYPE(COLOR_POINT) :: CPV = COLOR_POINT(POINT=PV, COLOR=3)
PRINT *, CPV%POINT ! Prints 1.0 and 2.0 PRINT *, CPV%POINT%X, CPV%POINT%Y ! And this does, too PRINT *, CPV%X, CPV%Y ! And this does, too
C.4.2 Allocation with dynamic type (9.7.1) 1 The following example illustrates the use of allocation with the value and dynamic type of the allocated object
given by another object. The example copies a list of objects of any type. It copies the list starting at IN_LIST.After copying, each element of the list starting at LIST_COPY has a polymorphic component, ITEM, for which
both the value and type are taken from the ITEM component of the corresponding element of the list starting at
IN_LIST.
TYPE :: LIST ! A list of anything
TYPE(LIST), POINTER :: NEXT => NULL()
CLASS(*), ALLOCATABLE :: ITEM
END TYPE LIST
...
TYPE(LIST), POINTER :: IN_LIST, LIST_COPY => NULL()
TYPE(LIST), POINTER :: IN_WALK, NEW_TAIL
! Copy IN_LIST to LIST_COPY
IF (ASSOCIATED(IN_LIST)) THEN
552 ⃝c ISO/IEC 2017 – All rights reserved
ISO/IEC DIS 1539-1:2017 (E)IN_WALK => IN_LIST
ALLOCATE(LIST_COPY)
NEW_TAIL => LIST_COPY
DO
ALLOCATE(NEW_TAIL%ITEM, SOURCE=IN_WALK%ITEM)
IN_WALK => IN_WALK%NEXT
IF (.NOT. ASSOCIATED(IN_WALK)) EXIT
ALLOCATE(NEW_TAIL%NEXT)
NEW_TAIL => NEW_TAIL%NEXT
END DO
END IF
C.5 Clause 10 notes C.5.1 Evaluation of function references (10.1.7) 1 If more than one function reference appears in a statement, they can be executed in any order (subject to a
function result being evaluated after the evaluation of its arguments) and their values cannot depend on the order1 A pointer is considered to be like any other variable when it is used as a primary in an expression. If a pointerof execution. This lack of dependence on order of evaluation enables parallel execution of the function references.
C.5.2 Pointers in expressions (<IP_ADDRESS>)
is used as an operand to an operator that expects a value, the pointer will automatically deliver the value stored1 The appearance of a pointer in a context that requires its value is a reference to its target. Similarly, where ain the space described by the pointer, that is, the value of the target object associated with the pointer.
C.5.3 Pointers in variable definition contexts (<IP_ADDRESS>, 19.6.7)
pointer appears in a variable definition context the variable that is defined is the target of the pointer.2 Executing the program fragment
REAL, POINTER :: Aproduces “42.0” as output.REAL, TARGET :: B = 10.0
A => B
A = 42.0
PRINT ’(F4.1)’, B
C.6 Clause 11 notes C.6.1 The SELECT CASE construct (11.1.9) 1 At most one case block is selected for execution within a SELECT CASE construct, and there is no fall-through
from one block into another block within a SELECT CASE construct. Thus there is no requirement for the user1 Fortran provides several forms of loop control:to exit explicitly from a block.
⃝c ISO/IEC 2017 – All rights reserved 553
ISO/IEC DIS 1539-1:2017 (E)
C.6.2 Loop control (11.1.7)
(1) With an iteration count and a DO variable. This is the classic Fortran DO loop.(2) Test a logical condition before each execution of the loop (DO WHILE).
(3) DO “forever”.
C.6.3 Examples of DO constructs (11.1.7) 1 The following are all valid examples of DO constructs.
Example 1:SUM = 0.0
READ (IUN) N
OUTER: DO L = 1, N ! A DO with a construct name
READ (IUN) IQUAL, M, ARRAY (1:M)
IF (IQUAL < IQUAL_MIN) CYCLE OUTER ! Skip inner loop
INNER: DO 40 I = 1, M ! A DO with a label and a name
CALL CALCULATE (ARRAY (I), RESULT)
IF (RESULT < 0.0) CYCLE
SUM = SUM + RESULT
IF (SUM > SUM_MAX) EXIT OUTER
40 END DO INNER
END DO OUTER
2 The outer loop has an iteration count of MAX (N, 0), and will execute that number of times or until SUM exceeds
SUM_MAX, in which case the EXIT OUTER statement terminates both loops. The inner loop is skipped by3 After execution of the above program fragment, I = 11, J = 10, K = 6, L = 5, and N = 50.the first CYCLE statement if the quality flag, IQUAL, is too low. If CALCULATE returns a negative RESULT,
the second CYCLE statement prevents it from being summed. Both loops have construct names and the inner
loop also has a label. A construct name is required in the EXIT statement in order to terminate both loops, but
is optional in the CYCLE statements because each belongs to its innermost loop.
Example 2:
N = 0
DO 50, I = 1, 10
J = I
DO K = 1, 5
L = K
N = N + 1 ! This statement executes 50 times
END DO ! Nonlabeled DO inside a labeled DO
50 CONTINUE
554 ⃝c ISO/IEC 2017 – All rights reserved
ISO/IEC DIS 1539-1:2017 (E)
Example 3:
N = 0
DO I = 1, 10
J = I
DO 60, K = 5, 1 ! This inner loop is never executed
L = K
N = N + 1
60 CONTINUE ! Labeled DO inside a nonlabeled DO
END DO
4 After execution of the above program fragment, I = 11, J = 10, K = 5, N = 0, and L is not defined by these
statements.1 The following are all examples of invalid skeleton DO constructs:C.6.4 Examples of invalid DO constructs (11.1.7)
Example 1:DO I = 1, 10
...
END DO LOOP ! No matching construct name
Example 2:
LOOP: DO 1000 I = 1, 10 ! No matching construct name
...
1000 CONTINUE
Example 3:
LOOP1: DO
...
END DO LOOP2 ! Construct names don’t match
Example 4:
DO I = 1, 10 ! Label required or ...
...
1010 CONTINUE ! ... END DO required
Example 5:
DO 1020 I = 1, 10
...
1021 END DO ! Labels don’t match
⃝c ISO/IEC 2017 – All rights reserved 555
ISO/IEC DIS 1539-1:2017 (E)
Example 6:
FIRST: DO I = 1, 10
SECOND: DO J = 1, 5
...
END DO FIRST ! Improperly nested DOs
END DO SECOND
C.6.5 Simple example using events 1 A tree is a graph in which every node except one has a single “parent” node to which it is connected by an edge.
The node without a parent is the “root” of the tree. The nodes that have a particular node as their parent are2 A multifrontal code to solve a sparse set of linear equations involves a tree. Work at a node can start after all ofthe “children” of that node. The root is at level 1, its children are at level 2, and so on.
its children’s work is complete and their data have been passed to it.3 Here we assume that each node has been assigned to an image. Each image has a list of its nodes and these
are ordered in decreasing tree level (all those at level L preceding those at level L − 1). For each node, arrayelements hold the number of children, details about the parent, and an event variable. This allows the processing
to proceed asynchronously subject to the rule that a parent has to wait for all its children.
Outline of example code:
PROGRAM TREE
USE, INTRINSIC :: ISO_FORTRAN_ENV
INTEGER, ALLOCATABLE :: NODE (:) ! Tree nodes that this image handles.
INTEGER, ALLOCATABLE :: PARENT (:), SUB (:)
INTEGER, ALLOCATABLE :: NC (:) ! NODE(I) has NC(I) children.
! The parent of NODE (I) is NODE (SUB (I)) [PARENT (I)].TYPE (EVENT_TYPE), ALLOCATABLE :: DONE (:) [:]
INTEGER :: I, J, STATUS
! Set up the tree, including allocation of all arrays.
DO I = 1, SIZE (NODE)
! Wait for children to completeIF (NC (I) > 0) THEN
EVENT WAIT (DONE (I), UNTIL_COUNT=NC (I), STAT=STATUS)
IF (STATUS/=0) EXIT
END IF
! Process node, using data from children.
IF (PARENT (I)>0) THEN
! Node is not the root.! Place result on image PARENT (I) for node NODE (SUB) [PARENT (I)]
! Tell PARENT (I) that this has been done.
EVENT POST (DONE (SUB (I)) [PARENT (I)], STAT=STATUS)
IF (STATUS/=0) EXIT
END IF
END DO
END PROGRAM TREE
556 ⃝c ISO/IEC 2017 – All rights reserved
ISO/IEC DIS 1539-1:2017 (E)
C.6.6 Example using three teams 1 The following example illustrates the structure of a routine that will compute fluxes based on surface properties
over land, sea, and ice, each in a different team. Each image will deal with areas containing exactly one of thethree surface types.
  Compute fluxes over sea surface
CALL COMPUTE_FLUXES_SEA (FLUX_MOM, FLUX_SENS, FLUX_LAT)
CASE (ICE) ! Compute fluxes over ice surface
CALL COMPUTE_FLUXES_ICE (FLUX_MOM, FLUX_SENS, FLUX_LAT)
CASE DEFAULT
ERROR STOP
END SELECT
END TEAM
END SUBROUTINE COMPUTE_FLUXES
C.6.7 Accessing coarrays in sibling teams 1 The following program illustrates subdividing a 4 × 4 grid into 2 × 2 teams, and the denotation of sibling teams.
PROGRAM DEMO
! Initial team : 16 images. Algorithm design is a 4 by 4 grid.
! Desire 4 teams, for the upper left (UL), upper right (UR),
⃝c ISO/IEC 2017 – All rights reserved 557
ISO/IEC DIS 1539-1:2017 (E)
! lower left (LL), lower right (LR)USE,INTRINSIC :: ISO_FORTRAN_ENV, ONLY: TEAM_TYPE
TYPE (TEAM_TYPE) :: T
INTEGER, PARAMETER :: UL=11, UR=22, LL=33, LR=44
REAL :: A(10,10)[4,*]
INTEGER :: MYPE, TEAMNUM, NEWPE
TYPE TRANS_T
INTEGER :: NEW_TEAM (16), NEW_INDEX (16)
END TYPE
TYPE (TRANS_T) :: TRANS
TRANS = TRANS_T ([UL, UL, LL, LL, UL, UL, LL, LL, UR, UR, LR, LR, UR, UR, LR, LR], &
[1, 2, 1, 2, 3, 4, 3, 4, 1, 2, 1, 2, 3, 4, 3, 4])MYPE = THIS_IMAGE ()
FORM TEAM (TRANS%NEW_TEAM(MYPE), T, NEW_INDEX=TRANS%NEW_INDEX(MYPE))
A = 3.14
CHANGE TEAM (T, B[2,*] => A)
! Inside change team, image pattern for B is a 2 by 2 grid.B (5, 5) = B (1, 1)[2, 1]
! Outside the team addressing:
NEWPE = THIS_IMAGE ()
SELECT CASE (TEAM_NUMBER ())
CASE (UL)
IF (NEWPE==3) THEN
! Right column of UL gets left column of UR.
B (:, 10) = B (:, 1)[1, 1, TEAM_NUMBER=UR]
ELSE IF (NEWPE==4) THEN
B (:, 10) = B (:, 1)[2, 1, TEAM_NUMBER=UR]
END IF
CASE (LL)
! Similar to complete column exchange across middle of the original grid....
END SELECT
END TEAM
END PROGRAM DEMO
C.6.8 Example involving failed images 1 Parallel algorithms often use work sharing schemes based on a specific mapping between image indices and global
data addressing. To allow such programs to continue when one or more images fail, spare images can be used2 The following example illustrates how this might be done. In this example, failure cannot be tolerated for imageto re-establish execution of the algorithm with the failed images replaced by spare images, while retaining the
previous image mapping for nonfailed images.
558 ⃝c ISO/IEC 2017 – All rights reserved
ISO/IEC DIS 1539-1:2017 (E)
1 in the initial team.
 Keep 1% spare images if we have a lot, just 1 if 10-199 images, 0 if <10.
images_spare = MAX (INT (0.01*NUM_IMAGES ()), 0, MIN (NUM_IMAGES () - 10, 1)
images_used = NUM_IMAGES () - images_spare
read_checkpoint = THIS_IMAGE () > images_used
setup : DO
me = THIS_IMAGE ()id = MERGE (1, 2, me<=images_used)
!
! Set up spare images as replacement for failed ones.
!
IF (IMAGE_STATUS (1) == STAT_FAILED_IMAGE) &
ERROR STOP "cannot recover"
IF (me == 1) THEN
failures = FAILED_IMAGES ()
k = images_used
DO i = 1, SIZE (failures)
DO k = k+1, NUM_IMAGES ()
IF (IMAGE_STATUS (k) == 0) EXIT
END DO
IF (k > NUM_IMAGES ()) ERROR STOP "cannot recover"
me [k] = failures (i)
id [k] = 1
END DO
images_used = k
END IF
!
! Set up a simulation team of constant size.
! Team 2 is the set of spares, so does not participate in the simulation.
!
FORM TEAM (id, simulation_team, NEW_INDEX=me, STAT=status)
simulation : CHANGE TEAM (simulation_team, STAT=status)
IF (status == STAT_FAILED_IMAGE) EXIT simulationIF (TEAM_NUMBER () == 1) THEN
iter : DO
⃝c ISO/IEC 2017 – All rights reserved 559
ISO/IEC DIS 1539-1:2017 (E)
CALL simulation_procedure (read_checkpoint, status, done)! The simulation_procedure:
! - sets up and performs some part of the simulation;
! - resets to the last checkpoint if requested;
! - sets status from its internal synchronizations;
! - sets done to .TRUE. when the simulation has completed.
IF (status == STAT_FAILED_IMAGE) THEN
read_checkpoint = .TRUE.
EXIT simulation
ELSE IF (done)
EXIT iter
END IF
read_checkpoint = .FALSE.
END DO iter
END IF
END TEAM simulation (STAT=status)
SYNC ALL (STAT=status)
IF (THIS_IMAGE () > images_used) done = done[1]
IF (done) EXIT setup
END DO setup
END PROGRAM possibly_recoverable_simulation
3 Supporting fault-tolerant execution imposes obligations on library writers who use the parallel language facilities.
Every synchronization statement, allocation or deallocation of coarrays, or invocation of a collective procedure1 This example is an adaptation of the later EVENT_QUERY example of C.11.2 to make it able to execute inwill need to be prepared to handle error conditions, and implicit deallocation of coarrays will need to be avoided.
Also, coarray module variables that are allocated inside the team execution context are not persistent.
C.6.9 EVENT_QUERY example that tolerates image failure
the presence of the failure of one or more of the worker images. The function create_work_item now accepts aninteger argument to indicate which work item is required. It is assumed that the work items are indexed 1, 2,
... . It is also assumed that if an image fails while processing a work item, that work item can subsequently be
processed by another image.
PROGRAM work_share
USE, INTRINSIC :: ISO_FORTRAN_ENV, ONLY: EVENT_TYPE
USE :: mod_work, ONLY: & ! Module that creates work items
work, & ! Type for holding a work item
create_work_item, & ! Function that creates work item
process_item, & ! Function that processes an item
work_done ! Logical function that returns true
! if all work done
TYPE :: worker_type
TYPE (EVENT_TYPE), ALLOCATABLE :: free (:)
END TYPE
560 c ISO/IEC 2017 – All rights reservedISO/IEC DIS 1539-1:2017 (E)
INTEGER :: count, i, k, kk, nbusy [*], np, status
TYPE (EVENT_TYPE) :: submit [*] ! Whether work ready for a worker TYPE (worker_type) :: worker [*] ! Whether worker is free TYPE (work) :: work_item [*] ! Holds the data for a work item INTEGER, ALLOCATABLE :: working (:) ! Items being worked on
INTEGER, ALLOCATABLE :: pending (:) ! Items pending after image failure
IF (THIS_IMAGE () == 1) THEN! Get started
ALLOCATE (worker%free (2:NUM_IMAGES ()))
ALLOCATE (working (2: NUM_IMAGES ()), pending(NUM_IMAGES ()-1))
nbusy = 0 ! This holds the number of workers working
k = 1 ! Index of next work item
np = 0 ! Number of work items in array pending
DO i = 2, NUM_IMAGES () ! Start the workers working
IF (work_done ()) EXIT
working (i) = 0
IF (IMAGE_STATUS (i) == STAT_FAILED_IMAGE) CYCLE
work_item [i] = create_work_item (k)
working (i) = k
k = k + 1
nbusy = nbusy + 1
EVENT POST (submit [i], STAT=status)
END DO
! Main work distribution loop
master : DO
image : DO i = 2, NUM_IMAGES ()IF (IMAGE_STATUS (i) == STAT_FAILED_IMAGE) THEN
IF (working (i)>0) THEN ! It failed while working
np = np + 1
pending (np) = working (i)
working (i) = 0
END IF
CYCLE image
END IF
CALL EVENT_QUERY (worker%free (i), count)
EVENT WAIT (worker%free (i))
IF (count == 0) CYCLE image ! Worker is not free nbusy = nbusy - 1
IF (np>0) THEN
kk = pending (np)np = np - 1
ELSE
IF (work_done ()) CYCLE image
kk = k
k = k + 1
⃝
c ISO/IEC 2017 – All rights reserved 561
ISO/IEC DIS 1539-1:2017 (E)
END IF
nbusy = nbusy + 1
working (i) = kk
work_item [i] = create_work_item (kk)
EVENT POST (submit [i], STAT=status)
! If image i has failed, the failure will be handled on
! the next iteration of the master loop.
END DO image
IF ( nbusy==0 ) THEN ! All done. Exit on all images.
 Work processing loop
worker : DO
EVENT WAIT (submit)END DO workerIF (nbusy [1] == 0) EXIT worker
CALL process_item(work_item)
EVENT POST (worker[1]%free (THIS_IMAGE ()))
END IF
END PROGRAM work_share
C.7 Clause 12 notes
C.7.1 External files (12.3) 1 This document accommodates, but does not require, file cataloging. To do this, several concepts are introduced. C.7.1.1 File existence (12.3.2)1 Totally independent of the connection state is the property of existence, this being a file property. The processor
“knows” of a set of files that exist at a given time for a given program. This set would include tapes ready to2 All four combinations of connection and existence can occur:read, files in a catalog, a keyboard, a printer, etc. The set might exclude files inaccessible to the program because
of security, because they are already in use by another program, etc. This document does not specify which
files exist, hence wide latitude is available to a processor to implement security, locks, privilege techniques, etc.
Existence is a convenient concept to designate all of the files that a program can potentially process.
562 ⃝c ISO/IEC 2017 – All rights reserved
ISO/IEC DIS 1539-1:2017 (E)
Connect Exist Examples3 Means are provided to create, delete, connect, and disconnect files.Yes Yes A card reader loaded and ready to be read
Yes No A printer before the first line is written
No Yes A file named ’JOAN’ in the catalog
No No A file on a reel of tape, not known to the processor
C.7.1.2 File access (12.3.3)1 This document does not address problems of security, protection, locking, and many other concepts that might
be part of the concept of “right of access”. Such concepts are considered to be in the province of an operating2 The OPEN and INQUIRE statements can be extended naturally to consider these things.system.
3 Possible access methods for a file are: sequential, stream and direct. The processor might implement three
different types of files, each with its own access method. It might instead implement one type of file with three4 Direct access to files is of a simple and commonly available type, that is, fixed-length records. The key is adifferent access methods.
positive integer.1 Before any input/output can be performed on a file, it needs to be connected to a unit. The unit then serves as aC.7.1.3 File connection (12.5)
designator for that file as long as it is connected. To be connected does not imply that “buffers” have or have not1 A file can have a name. The form of a file name is not specified. If a system does not have some form of catalogingbeen allocated, that “file-control tables” have or have not been filled, or that any other method of implementation
has been used. Connection means that (barring some other fault) a READ or WRITE statement can be executed
on the unit, hence on the file. Without a connection, a READ or WRITE statement cannot be executed.
C.7.1.4 File names (<IP_ADDRESS>)
or tape labeling for at least some of its files, all file names disappear at the termination of execution. This is a1 Data transfer statements affect the positioning of an external file. In Fortran 77, if no error or end-of-filevalid implementation. Nowhere does this document require names to survive for any period of time longer than
the execution time span of a program. Therefore, this document does not impose cataloging as a prerequisite.
The naming feature is intended to enable use of a cataloging system where one exists.
C.7.2 Nonadvancing input/output (<IP_ADDRESS>)
condition exists, the file is positioned after the record just read or written and that record becomes the preceding2 The tab edit descriptor and the slash are still appropriate for use with this type of record access but the tabrecord. This document contains the ADVANCE= specifier in a data transfer statement that provides the capab-
ility of maintaining a position within the current record from one formatted data transfer statement to the next
data transfer statement. The value NO provides this capability. The value YES positions the file after the record
just read or written. The default is YES.
⃝c ISO/IEC 2017 – All rights reserved 563
ISO/IEC DIS 1539-1:2017 (E)
cannot reposition before the left tab limit.3 A BACKSPACE of a file that is positioned within a record causes the specified unit to be positioned before the
current record.4 If the next input/output operation on a file after a nonadvancing write is a rewind, backspace, end file or close
operation, the file is positioned implicitly after the current record before an ENDFILE record is written to the5 This document provides a SIZE= specifier to be used with formatted data transfer statements. The variable infile, that is, a REWIND, BACKSPACE, or ENDFILE statement following a nonadvancing WRITE statement
causes the file to be positioned at the end of the current output record before the endfile record is written to the
file.
the SIZE= specifier is assigned the count of the number of characters that make up the sequence of values read6 The count is especially helpful if there is only one list item in the input list because it is the number of charactersby the data edit descriptors in the input statement.
that appeared for the item.7 The EOR= specifier is provided to indicate when an EOR condition is encountered during a nonadvancing data
transfer statement. The EOR condition is not an error condition. If this specifier appears, an input list item that8 For nonadvancing input, the processor is not required to read partial records. The processor could read the entirerequires more characters than the record contained is padded with blanks if PAD= ’YES’ is in effect. This means
that the input list item completed successfully. The file is positioned after the current record. If the IOSTAT=
specifier appears, the specified variable is defined with the value of the named constant IOSTAT_EOR from
the intrinsic module ISO_FORTRAN_ENV and the data transfer statement is terminated. Program execution
continues with the statement specified in the EOR= specifier. The EOR= specifier gives the capability of taking
control of execution when the EOR condition is encountered. The do-variables in io-implied-dos retain their last
defined value and any remaining items in the input-item-list retain their definition status when an EOR condition
occurs. If the SIZE= specifier appears, the specified variable is assigned the number of characters read with the
data edit descriptors during the READ statement.
record into an internal buffer and make successive portions of the record available to successive input statements.9 In an implementation of nonadvancing input/output in which a nonadvancing write to a terminal device causes
immediate display of the output, such a write can be used as a mechanism to output a prompt. In this case, the10 The response, which might be read by a statement of the formstatement
WRITE (*, FMT=’(A)’, ADVANCE=’NO’) ’CONTINUE?(Y/N): ’
would result in the prompt
CONTINUE?(Y/N):
being displayed with no subsequent line feed.
READ (*, FMT=’(A)’) ANSWERcan then be entered on the same line as the prompt as in
CONTINUE?(Y/N): Y
564 ⃝c ISO/IEC 2017 – All rights reserved
ISO/IEC DIS 1539-1:2017 (E)11 This document does not require that an implementation of nonadvancing input/output operate in this manner.
For example, an implementation of nonadvancing output in which the display of the output is deferred until1 A file can become connected to a unit either by preconnection or by execution of an OPEN statement. Precon-the current record is complete is also standard-conforming. Such an implementation will not, however, allow a
prompting mechanism of this kind to operate.
C.7.3 OPEN statement (12.5.6)
nection is performed prior to the beginning of execution of a program by means external to Fortran. For example,2 The OPEN statement provides a means to access existing files that are not preconnected. An OPEN statementit could be done by job control action or by processor-established defaults. Execution of an OPEN statement is
not required in order to access preconnected files (12.5.5).
can be used in either of two ways: with a file name (open-by-name) and without a file name (open-by-unit). A3 Therefore, there are three ways a file can become connected and hence processed: preconnection, open-by-name,unit is given in either case. Open-by-name connects the specified file to the specified unit. Open-by-unit connects
a processor-dependent default file to the specified unit. (The default file might or might not have a name.)
and open-by-unit. Once a file is connected, there is no means in standard Fortran to determine how it became4 An OPEN statement can also be used to create a new file. In fact, any of the foregoing three connection methodsconnected.
can be performed on a file that does not exist. When a unit is preconnected, writing the first record creates the5 When an OPEN statement is executed, the unit specified in the OPEN statement might or might not already befile. With the other two methods, execution of the OPEN statement creates the file.
connected to a file. If it is already connected to a file (either through preconnection or by prior execution of an6 If the value of the ACTION= specifier is WRITE, then a READ statement cannot refer to the connection.OPEN statement), then omitting the FILE= specifier in the OPEN statement implies that the file is to remain
connected to the unit. Such an OPEN statement can be used to change the values of the blank interpretation
mode, decimal edit mode, pad mode, input/output rounding mode, delimiter mode, and sign mode.
ACTION = ’WRITE’ does not restrict positioning by a BACKSPACE statement or positioning specified by the7 The following examples illustrate these rules. In the first example, unit 10 is preconnected to a SCRATCH file;POSITION= specifier with the value APPEND. However, a BACKSPACE statement or an OPEN statement
containing POSITION = ’APPEND’ might fail if the processor needs to read the file to achieve the positioning.
the OPEN statement changes the value of PAD= to YES.8 In the next example, unit 12 is first connected to a file named FRED, with a status of OLD. The second OPENCHARACTER (LEN = 20) CH1
WRITE (10, ’(A)’) ’THIS IS RECORD 1’
OPEN (UNIT = 10, STATUS = ’OLD’, PAD = ’YES’)
REWIND 10
READ (10, ’(A20)’) CH1 ! CH1 now has the value
! ’THIS IS RECORD 1 ’
statement then opens unit 12 again, retaining the connection to the file FRED, but changing the value of the9 The next example is invalid because it attempts to change the value of the STATUS= specifier.DELIM= specifier to QUOTE.
⃝c ISO/IEC 2017 – All rights reserved 565
ISO/IEC DIS 1539-1:2017 (E)
CHARACTER (LEN = 25) CH2, CH3
OPEN (12, FILE = ’FRED’, STATUS = ’OLD’, DELIM = ’NONE’)
CH2 = ’"THIS STRING HAS QUOTES."’
! Quotes in string CH2
WRITE (12, *) CH2 ! Written with no delimiters
OPEN (12, DELIM = ’QUOTE’) ! Now quote is the delimiter
REWIND 12
READ (12, *) CH3 ! CH3 now has the value
! ’THIS STRING HAS QUOTES. ’
OPEN (10, FILE = ’FRED’, STATUS = ’OLD’)10 The previous example could be made valid by closing the unit first, as in the next example.WRITE (10, *) A, B, C
OPEN (10, STATUS = ’SCRATCH’) ! Attempts to make FRED a SCRATCH file
OPEN (10, FILE = ’FRED’, STATUS = ’OLD’)WRITE (10, *) A, B, C
CLOSE (10)
OPEN (10, STATUS = ’SCRATCH’) ! Opens a different SCRATCH file
C.7.4 Connection properties (12.5.4) 1 When a unit becomes connected to a file, either by execution of an OPEN statement or by preconnection, the following connection properties, among others, are established.2 A processor has wide latitude in adapting these concepts and actions to its own cataloging and job control(1) An access method, which is sequential, direct, or stream, is established for the connection (<IP_ADDRESS>).
(2) A form, which is formatted or unformatted, is established for a connection to a file that exists or
is created by the connection. For a connection that results from execution of an OPEN statement,
a default form (which depends on the access method, as described in 12.3.3) is established if no
form is specified. For a preconnected file that exists, a form is established by preconnection. For a
preconnected file that does not exist, a form might be established, or the establishment of a form
might be delayed until the file is created (for example, by execution of a formatted or unformatted
WRITE statement) (<IP_ADDRESS>).
(3) A record length might be established. If the access method is direct, the connection establishes a
record length that specifies the length of each record of the file. A direct access file can only contain
records that are all of equal length.
(4) A sequential file can contain records of varying lengths. In this case, the record length established
specifies the maximum length of a record in the file (<IP_ADDRESS>).
conventions. Some processors might need job control action to specify the set of files that exist or that will3 The meaning of “open” in contexts other than Fortran might include such things as mounting a tape, consolebe created by a program. Some processors might not need any job control action prior to execution. This
document enables processors to perform dynamic open, close, or file creation operations, but it does not require
such capabilities of the processor.
566 ⃝
c ISO/IEC 2017 – All rights reserved
ISO/IEC DIS 1539-1:2017 (E)
messages, spooling, label checking, security checking, etc. These actions might occur upon job control action1 Rather than limit support for asynchronous input/output to what has been traditionally provided by facilitiesexternal to Fortran, upon execution of an OPEN statement, or upon execution of the first read or write of the
file. The OPEN statement describes properties of the connection to the file and might or might not cause physical
activities to take place.
C.7.5 Asynchronous input/output (<IP_ADDRESS>)
such as BUFFERIN/BUFFEROUT, this document builds upon existing Fortran syntax. This permits alternative2 Not all processors actually perform input/output asynchronously, nor will every processor that does be able toapproaches for implementing asynchronous input/output, and simplifies the task of adapting existing standard-
conforming programs to use asynchronous input/output.
handle data transfer statements with complicated input/output item lists in an asynchronous manner. Such3 This document allows for at least two different conceptual models for asynchronous input/output.processors can still be standard-conforming.
4 Model 1: the processor performs asynchronous input/output when the item list is simple (perhaps one contiguous
named array) and the input/output is unformatted. The implementation cost is reduced, and this is the scenario5 Model 2: The processor is free to do any of the following:most likely to be beneficial on traditional “big-iron” machines.
(1) on output, create a buffer inside the input/output library, completely formatted, and then start an6 A program can issue a large number of asynchronous input/output requests, without waiting for any of them toasynchronous write of the buffer, and immediately return to the next statement in the program. The
processor is free to wait for previously issued WRITEs, or not, or
(2) pass the input/output list addresses to another processor/process, which processes the list items
independently of the processor that executes the user’s code. The addresses of the list items will
need to be computed before the asynchronous READ/WRITE statement completes. There is still
an ordering requirement on list item processing to handle things like READ (...) N,(a(i),i=1,N).
complete, and then wait for any or all of them. That does not constitute a requirement for the processor to keep7 It is not necessary for all requests to be tracked by the runtime library. If an ID= specifier does not appear in on atrack of each individual request separately.
READ or WRITE statement, the runtime library can forget about this particular request once it has successfully8 The requirement to set the IOSTAT variable correctly means that a processor will need to remember whichcompleted. If an error or end-of-file condition occurs for a request, the processor can report this during any
input/output operation to that unit. If an ID= specifier appears, the processor’s runtime input/output library
will need to keep track of any end-of-file or error conditions for that particular input/output request. However, if
the input/output request succeeds without any exceptional conditions occurring, then the runtime can forget that
ID= value. A runtime library might only keep track of the last request made, or perhaps a very few. Then, when
a user WAITs for a particular request, either the library will know about it (and does the right thing with respect
to error handling, etc.), or can assume it is a request that successfully completed and was forgotten about (and
will just return without signaling any end-of-file or error condition). A standard-conforming program can only
pass valid ID= values, but there is no requirement on the processor to detect invalid ID= values. There might
be a processor dependent limit on how many outstanding input/output requests that generate an end-of-file or
⃝c ISO/IEC 2017 – All rights reserved 567
ISO/IEC DIS 1539-1:2017 (E)
error condition can be handled before the processor runs out of memory to keep track of such conditions. The
restrictions on the SIZE= variables are designed to enable the processor to update such variables at any time
(after the request has been processed, but before the wait operation), and then forget about them. Only error and
end-of-file conditions are expected to be tracked by individual request by the runtime, and then only if an ID=
specifier appears. The END= and EOR= specifiers have not been added to all statements that can perform wait
operations. Instead, the IOSTAT variable can be queried after a wait operation to handle this situation. This
choice was made because the WAIT statement is expected to be the usual method of waiting for input/output
to complete (and WAIT does support the END= and EOR= specifiers). This particular choice is philosophical,
and was not based on significant technical difficulties.
input/output requests encountered an end-of-record condition, so that a subsequent wait operation can return1 The number of records read by an explicitly formatted advancing input statement can be determined from thethe correct IOSTAT value. Therefor there might be a processor defined limit on the number of outstanding
nonadvancing input/output requests that have encountered an end-of-record condition (constrained by available
memory to keep track of this information, similar to end-of-file and error conditions).
C.8 Clause 13 notes
C.8.1 Number of records (13.4, 13.5, 13.8.2)
following rule: a record is read at the beginning of the format scan (even if the input list is empty unless the most2 The number of records written by an explicitly formatted advancing output statement can be determined fromrecently previous operation on the unit was not a nonadvancing read operation), at each slash edit descriptor
encountered in the format, and when a format rescan occurs at the end of the format.
the following rule: a record is written when a slash edit descriptor is encountered in the format, when a format1 The following examples illustrate list-directed input. A blank character is represented by b.rescan occurs at the end of the format, and at completion of execution of an advancing output statement (even if
the output list is empty). Thus, the occurrence of n successive slashes between two other edit descriptors causes
n − 1 blank lines if the records are printed. The occurrence of n slashes at the beginning or end of a complete
format specification causes n blank lines if the records are printed. However, a complete format specification
containing n slashes (n > 0) and no other edit descriptors causes n + 1 blank lines if the records are printed. For
example, the statements
PRINT 3
3 FORMAT (/)
will write two records that cause two blank lines if the records are printed.
C.8.2 List-directed input (13.10.3)
2 Example 1:
Program:3 Result: I = 1, J = 3.J = 3
READ *, I
READ *, J
568 ⃝
c ISO/IEC 2017 – All rights reserved
ISO/IEC DIS 1539-1:2017 (E)
Sequential input file:
record 1: b1b,4bbbbb
record 2: ,2bbbbbbbb
4 Explanation: The second READ statement reads the second record. The initial comma in the record designates
a null value; therefore, J is not redefined.5 Example 2:
Program:6 Result: A = ’bbbbbbbb’, B = ’Q’CHARACTER A *8, B *1
READ *, A, B
Sequential input file:
record 1: ’bbbbbbbb’
record 2: ’QXY’b’Z’
7 Explanation: In the first record, the rightmost apostrophe is interpreted as delimiting the constant (it cannot
be the first of a pair of embedded apostrophes representing a single apostrophe because this would involve1 The name of the main program or of a block data program unit has no explicit use within the Fortran language.the prohibited “splitting” of the pair by the end of a record); therefore, A is assigned the character constant
’bbbbbbbb’. The end of a record acts as a blank, which in this case is a value separator because it occurs between
two constants.
C.9 Clause 14 notes
C.9.1 Main program and block data program unit (14.1, 14.3)
It is available for documentation and for possible use by a processor.2 A processor might implement an unnamed program unit by assigning it a global identifier that is not used
elsewhere in the program. This could be done by using a default name that does not satisfy the rules for Fortran1 This document, like its predecessors, is intended to enable the implementation of conforming processors in whichnames.
C.9.2 Dependent compilation (14.2)
a program can be broken into multiple units, each of which can be separately translated in preparation for2 The dependencies involved here are new only in the sense that the Fortran processor is now aware of them. Theexecution. Such processors are commonly described as supporting separate compilation. There is an important
difference between the way separate compilation can be implemented under this document and the way it could be
implemented under the Fortran 77 International Standard. Under the Fortran 77 standard, any information
⃝c ISO/IEC 2017 – All rights reserved 569
ISO/IEC DIS 1539-1:2017 (E)
required to translate a program unit was specified in that program unit. Each translation was thus totally
independent of all others. Under this document, a program unit can use information that was specified in a
separate module and thus can be dependent on that module. The implementation of this dependency in a
processor might be that the translation of a program unit depends on the results of translating one or more
modules. Processors implementing the dependency this way are commonly described as supporting dependent
compilation.
same information dependencies existed under the Fortran 77 International Standard, but it was the program-3 The exact meaning of the requirement that the public portions of a module be available at the time of referencemer’s responsibility to transport the information necessary to resolve them by making redundant specifications of
the information in multiple program units. The availability of separate but dependent compilation offers several
potential advantages over the redundant textual specification of information.
(1) Specifying information at a single place in the program ensures that different program units using that
information are translated consistently. Redundant specification leaves the possibility that different
information can be erroneously be specified. Even if an INCLUDE line is used to ensure that the
text of the specifications is identical in all involved program units, the presence of other specifications
(for example, an IMPLICIT statement) could change the interpretation of that text.
(2) During the revision of a program, it is possible for a processor to assist in determining whether differ-
ent program units have been translated using different (incompatible) versions of a module, although
there is no requirement that a processor provide such assistance. Inconsistencies in redundant textual
specification of information, on the other hand, tend to be much more difficult to detect.
(3) Putting information in a module provides a way of packaging it. Without modules, redundant spe-
cifications frequently are interleaved with other specifications in a program unit, making convenient
packaging of such information difficult.
(4) Because a processor can be implemented such that the specifications in a module are translated once
and then repeatedly referenced, there is the potential for greater efficiency than when the processor
translates redundant specifications of information in multiple program units.
is processor dependent. For example, a processor could consider a module to be available only after it has been1 Another benefit of the USE statement is its enhanced facilities for name management. If one needs to use onlycompiled and require that if the module has been compiled separately, the result of that compilation be identified
to the compiler when compiling program units that use it.
C.9.2.1 USE statement and dependent compilation (14.2.2)
selected entities in a module, one can do so without having to worry about the names of all the other entities2 A benefit of using the ONLY option consistently, as compared to USE without it, is that the module from whichin that module. If one needs to use two different modules that happen to contain entities with the same name,
there are several ways to deal with the conflict. If none of the entities with the same name are to be used, they
can simply be ignored. If the name happens to refer to the same entity in both modules (for example, if both
modules obtained it from a third module), then there is no confusion about what the name denotes and the name
can be freely used. If the entities are different and one or both is to be used, the local renaming facility in the
USE statement makes it possible to give those entities different names in the program unit containing the USE
statements.
each accessed entity is accessed is explicitly specified in each program unit. This means that one need not search3 A typical implementation of dependent but separate compilation might involve storing the result of translating aother program units to find where each one is defined. This reduces maintenance costs.
570 ⃝c ISO/IEC 2017 – All rights reserved
ISO/IEC DIS 1539-1:2017 (E)
module in a file whose name is derived from the name of the module. Note, however, that the name of a module4 The result of translating a module could reasonably either contain only the information textually specified in theis limited only by the Fortran rules and not by the names allowed in the file system. Thus the processor might
have to provide a mapping between Fortran names and file system names.
module (with “pointers” to information originally textually specified in other modules) or contain all information5 There is an increased potential for undetected errors in a scoping unit that uses both implicit typing and thespecified in the module (including copies of information originally specified in other modules). Although the former
approach would appear to save on storage space, the latter approach can greatly simplify the logic necessary to
process a USE statement and can avoid the necessity of imposing a limit on the logical “nesting” of modules via
the USE statement.
USE statement. For example, in the program fragment
SUBROUTINE SUB
USE MY_MODULE
IMPLICIT INTEGER (I-N), REAL (A-H, O-Z)
X = F (B)
A = G (X) + H (X + 1)
END SUBROUTINE SUB
X could be either an implicitly typed real variable or a variable obtained from the module MY_MODULE and
might change from one to the other because of changes in MY_MODULE unrelated to the action performed by
SUB. Logic errors resulting from this kind of situation can be extremely difficult to locate. Thus, the use of these
features together is discouraged.
C.9.2.2 Accessibility attributes (8.5.2) 1 The PUBLIC and PRIVATE attributes, which can be declared only in modules, divide the entities in a module
into those that are actually relevant to a scoping unit referencing the module and those that are not. This1 A module could contain only data objects, for example:information might be used to improve the performance of a Fortran processor. For example, it might be possible
to discard much of the information about the private entities once a module has been translated, thus saving on
both storage and the time to search it. Similarly, it might be possible to recognize that two versions of a module
differ only in the private entities they contain and avoid retranslating program units that use that module when
switching from one version of the module to the other.
C.9.3 Examples of the use of modules (14.2.1)
C.9.3.1 Global data (14.2.1)
MODULE DATA_MODULE
SAVE
REAL A (10), B, C (20,20)
INTEGER :: I=0
INTEGER, PARAMETER :: J=10
COMPLEX D (J,J)
END MODULE DATA_MODULE
⃝c ISO/IEC 2017 – All rights reserved 571
ISO/IEC DIS 1539-1:2017 (E)2 Data objects made global in this manner can have any combination of data types.
3 Access to some of these can be made by a USE statement with the ONLY option, such as:
USE DATA_MODULE, ONLY: A, B, Dand access to all of them can be made by the following USE statement:
USE DATA_MODULE
4 Access to all of them with some renaming to avoid name conflicts can be made by, for example:
USE DATA_MODULE, AMODULE => A, DMODULE => D
C.9.3.2 Derived types (14.2.1) 1 A derived type can be defined in a module and accessed in a number of program units. For example,
MODULE SPARSE
TYPE NONZERO
REAL A
INTEGER I, J
END TYPE NONZERO
END MODULE SPARSE
defines a type consisting of a real component and two integer components for holding the numerical value of a
nonzero matrix element and its row and column indices.
C.9.3.3 Global allocatable arrays (14.2.1) 1 Many programs need large global allocatable arrays whose sizes are not known before program execution. A
simple form for such a program is:
PROGRAM GLOBAL_WORK
CALL CONFIGURE_ARRAYS ! Perform the appropriate allocations CALL COMPUTE ! Use the arrays in computations END PROGRAM GLOBAL_WORK
MODULE WORK_ARRAYS ! An example set of work arrays INTEGER N
REAL, ALLOCATABLE :: A (:), B (:, :), C (:, :, :)
END MODULE WORK_ARRAYS
SUBROUTINE CONFIGURE_ARRAYS ! Process to set up work arrays USE WORK_ARRAYS
READ (*, *) N
ALLOCATE (A (N), B (N, N), C (N, N, 2 * N))
END SUBROUTINE CONFIGURE_ARRAYS
SUBROUTINE COMPUTE
USE WORK_ARRAYS
... ! Computations involving arrays A, B, and C
END SUBROUTINE COMPUTE
572 ⃝c ISO/IEC 2017 – All rights reserved
ISO/IEC DIS 1539-1:2017 (E)2 Typically, many subprograms need access to the work arrays, and all such subprograms would contain the
statement
USE WORK_ARRAYS
C.9.3.4 Procedure libraries (14.2.2) 1 Interface bodies for external procedures in a library can be gathered into a module. An interface body specifies
an explicit interface (<IP_ADDRESS>).2 An example is the following library module:
MODULE LIBRARY_LLS
INTERFACE
SUBROUTINE LLS (X, A, F, FLAG)
REAL X (:, :)! The SIZE in the next statement is an intrinsic function
REAL, DIMENSION (SIZE (X, 2)) :: A, F
INTEGER FLAG
END SUBROUTINE LLS
...
END INTERFACE
...
END MODULE LIBRARY_LLS
3 This module provides an explicit interface that is necessary for the subroutine LLS to be invoked. for example:
USE LIBRARY_LLS
...
CALL LLS (X = ABC, A = D, F = XX, FLAG = IFLAG)
...4 Because dummy argument names in an interface body for an external procedure are not required to be the same
as in the procedure definition, different versions can be constructed for different applications using argument1 In order to extend an intrinsic operator symbol to have an additional meaning, an interface block specifying thatkeywords appropriate to each application.
C.9.3.5 Operator extensions (14.2.2)
operator symbol in the OPERATOR option of the INTERFACE statement could be placed in a module.2 For example, // can be extended to perform concatenation of two derived-type objects serving as varying length
character strings and + can be extended to specify matrix addition for type MATRIX or interval arithmetic3 A module might contain several such interface blocks. An operator can be defined by an external function (eitheraddition for type INTERVAL.
in Fortran or some other language) and its procedure interface placed in the module.1 In addition to providing a portable means of avoiding the redundant specification of information in multiple⃝c ISO/IEC 2017 – All rights reserved 573
ISO/IEC DIS 1539-1:2017 (E)
C.9.3.6 Data abstraction (14.2.2)
program units, a module provides a convenient means of “packaging” related entities, such as the definitions of2 The transfer function SETF converts a vector of integer values to the corresponding set, with duplicate valuesthe representation and operations of an abstract data type. The following example of a module defines a data
abstraction for a SET type where the elements of each set are of type integer. The usual set operations of UNION,
INTERSECTION, and DIFFERENCE are provided. The CARDINALITY function returns the cardinality of
(number of elements in) its set argument. Two functions returning logical values are included, ELEMENT and
SUBSET. ELEMENT defines the operator .IN. and SUBSET extends the operator <=. ELEMENT determines
if a given scalar integer value is an element of a given set, and SUBSET determines if a given set is a subset of
another given set. (Two sets can be checked for equality by comparing cardinality and checking that one is a
subset of the other, or checking to see if each is a subset of the other.)
removed. Thus, a vector of constant values can be used as set constants. An inverse transfer function VECTOR3 Here is the example module:returns the elements of a set as a vector of values in ascending order. In this SET implementation, set data
objects have a maximum cardinality of 200.
MODULE INTEGER_SETS
! This module is intended to illustrate use of the module facility
! to define a new type, along with suitable operators.
INTEGER, PARAMETER :: MAX_SET_CARD = 200
TYPE SET ! Define SET type PRIVATE
INTEGER CARD
INTEGER ELEMENT (MAX_SET_CARD)
END TYPE SET
INTERFACE OPERATOR (.IN.)
MODULE PROCEDURE ELEMENT
END INTERFACE OPERATOR (.IN.)
INTERFACE OPERATOR (<=)
MODULE PROCEDURE SUBSET
END INTERFACE OPERATOR (<=)
INTERFACE OPERATOR (+)
MODULE PROCEDURE UNION
END INTERFACE OPERATOR (+)
INTERFACE OPERATOR (-)
MODULE PROCEDURE DIFFERENCE
END INTERFACE OPERATOR (-)
574 c ISO/IEC 2017 – All rights reservedISO/IEC DIS 1539-1:2017 (E)
INTERFACE OPERATOR (*)
MODULE PROCEDURE INTERSECTION
END INTERFACE OPERATOR (*)
CONTAINS
INTEGER FUNCTION CARDINALITY (A) ! Returns cardinality of set A TYPE (SET), INTENT (IN) :: ACARDINALITY = A % CARD
END FUNCTION CARDINALITY
LOGICAL FUNCTION ELEMENT (X, A) ! Determines if INTEGER, INTENT(IN) :: X ! element X is in set ATYPE (SET), INTENT(IN) :: A
ELEMENT = ANY (A % ELEMENT (1 : A % CARD) == X)
END FUNCTION ELEMENT
FUNCTION UNION (A, B) ! Union of sets A and B TYPE (SET) UNIONTYPE (SET), INTENT(IN) :: A, B
INTEGER J
UNION = A
DO J = 1, B % CARD
IF (.NOT. (B % ELEMENT (J) .IN. A)) THENIF (UNION % CARD < MAX_SET_CARD) THEN
UNION % CARD = UNION % CARD + 1
UNION % ELEMENT (UNION % CARD) = B % ELEMENT (J)
ELSE
! Maximum set size exceeded . . .
END IF
END IF
END DO
END FUNCTION UNION
FUNCTION DIFFERENCE (A, B) ! Difference of sets A and B TYPE (SET) DIFFERENCETYPE (SET), INTENT(IN) :: A, B
INTEGER J, X
DIFFERENCE % CARD = 0 ! The empty set
DO J = 1, A % CARD
X = A % ELEMENT (J)
IF (.NOT. (X .IN. B)) DIFFERENCE = DIFFERENCE + SET (1, X)
END DO
END FUNCTION DIFFERENCE
FUNCTION INTERSECTION (A, B) ! Intersection of sets A and B ⃝
c ISO/IEC 2017 – All rights reserved 575
ISO/IEC DIS 1539-1:2017 (E)
TYPE (SET) INTERSECTIONTYPE (SET), INTENT(IN) :: A, B
INTERSECTION = A - (A - B)
END FUNCTION INTERSECTION
LOGICAL FUNCTION SUBSET (A, B) ! Determines if set A is TYPE (SET), INTENT(IN) :: A, B ! a subset of set B
INTEGER I
SUBSET = A % CARD <= B % CARD
DO I = 1, A % CARD
IF (.NOT. SUBSET) RETURN ! For efficiency
SUBSET = SUBSET .AND. (A % ELEMENT (I) .IN. B)
END DO
END FUNCTION SUBSET
TYPE (SET) FUNCTION SETF (V) ! Transfer function between a vector INTEGER V (:) ! of elements and a set of elementsINTEGER J ! removing duplicate elements
SETF % CARD = 0
DO J = 1, SIZE (V)
IF (.NOT. (V (J) .IN. SETF)) THEN
IF (SETF % CARD < MAX_SET_CARD) THEN
SETF % CARD = SETF % CARD + 1
SETF % ELEMENT (SETF % CARD) = V (J)
ELSE
! Maximum set size exceeded . . .
END IF
END IF
END DO
END FUNCTION SETF
FUNCTION VECTOR (A) ! Transfer the values of set A TYPE (SET), INTENT (IN) :: A ! into a vector in ascending orderINTEGER, POINTER :: VECTOR (:)
INTEGER I, J, K
ALLOCATE (VECTOR (A % CARD))
VECTOR = A % ELEMENT (1 : A % CARD)
DO I = 1, A % CARD - 1 ! Use a better sort if
DO J = I + 1, A % CARD ! A % CARD is large
IF (VECTOR (I) > VECTOR (J)) THEN
K = VECTOR (J); VECTOR (J) = VECTOR (I); VECTOR (I) = K
END IF
END DO
END DO
END FUNCTION VECTOR
END MODULE INTEGER_SETS
1 At times it might be necessary to rename entities that are accessed with USE statements.
576 c ISO/IEC 2017 – All rights reserved4 Examples of using INTEGER_SETS (A, B, and C are variables of type SET; X is an integer variable):
ISO/IEC DIS 1539-1:2017 (E)
! Check to see if A has more than 10 elementsIF (CARDINALITY (A) > 10) ...
! Check for X an element of A but not of B
IF (X .IN. (A - B)) ...
! C is the union of A and the result of B intersected
! with the integers 1 to 100
C = A + B * SETF ([(I, I = 1, 100)])
! Does A have any even numbers in the range 1:100?
IF (CARDINALITY (A * SETF ([(I, I = 2, 100, 2)])) > 0) ...