From owner-sc22wg5  Wed Aug  7 17:27:56 2002
Received: from nameserv.rl.ac.uk (nameserv.rl.ac.uk [130.246.135.129])
	by dkuug.dk (8.9.2/8.9.2) with ESMTP id RAA89142
	for <SC22WG5@dkuug.dk>; Wed, 7 Aug 2002 17:27:56 +0200 (CEST)
	(envelope-from jkr@jkr.cc.rl.ac.uk)
Received: from jkr.cc.rl.ac.uk (jkr.cc.rl.ac.uk [130.246.8.20])
	by nameserv.rl.ac.uk (8.8.8/8.8.8) with ESMTP id QAA09249
	for <SC22WG5@dkuug.dk>; Wed, 7 Aug 2002 16:28:39 +0100
Received: (from jkr@localhost)
	by jkr.cc.rl.ac.uk (8.8.8+Sun/8.8.8) id QAA08773
	for SC22WG5@dkuug.dk; Wed, 7 Aug 2002 16:32:19 +0100 (BST)
Date: Wed, 7 Aug 2002 16:32:19 +0100 (BST)
From: John Reid <jkr@rl.ac.uk>
Message-Id: <200208071532.QAA08773@jkr.cc.rl.ac.uk>
To: SC22WG5@dkuug.dk
Subject: Summary of the new features of Fortran 2000
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"

Dear WG5,

In April, I said:
 
> I also want to tell you that I have committed myself to writing a
> 32-page summary of the new standard for Fortran Forum. It will appear
> as a special issue and I need to send it to Mike Metcalf in the week
> following our meeting. This means that I must write a draft before the
> meeting and I will be inviting you to comment on it. I hope you agree
> that publishing such a summary is important. We can make it an official
> WG5 document if you wish, but we must not be distracted from the main
> task of getting the standard ready.

I was optimistic about the time it would take me to prepare this
summary. J3 really has been working hard. There is a lot of new stuff.

I meant to send you a draft before this, but it was too unfinished.  It
is still unfinished, but here it is. All comments are most welcome.  I
will put whatever I have tomorrow (my last day before leaving for LV)
on the server then. I plan to work more on it during our meeting.  I
will keep it as a text document until I get back, when I will typeset
it.

Best wishes,

John. 

................................................................


                THE NEW FEATURES OF FORTRAN 2000

                    John Reid, WG5 Convener

1. INTRODUCTION

The aim of this paper is to summarize the new features in the draft 
Fortran 2000 standard (J3 2002). We take as our starting point 
Fortran 95 plus the two official extensions (Cohen 2001, Reid 2001) 
that have been published as Type 2 Technical Reports. These provide 
features for 

   1. Allocatable dummy arguments and type components

   2. Exception handling and support of the IEEE Floating Point standard

There is a firm commitment to include the features of these TRs in 
Fortran 2000, apart from changes that follow from errors and omissions 
found during implementation. Therefore, these features are not open to 
comment and are not described here. For an informal description, see
chapters 12 and 13 of Metcalf and Reid (1999).

Fortran 2000 is a major extension of Fortran 95. This contrasts with 
Fortran 95, which was a minor extension of Fortran 90. 

We hope that this will help people to prepare comments, but it is not
an official document and has not been approved by either WG5 or J3.
Comments should be based on the draft itself (J3 2002). Note that it is
accessible via the web.


2. DATA ENHANCEMENTS AND OBJECT ORIENTATION

2.1 Parameterized derived types

An obvious deficiency of Fortran 95 is that whereas each of the
intrinsic types has a kind parameter and character type has a length
parameter, it is not possible to define a parameterized derived type.
This deficiency is remedied with a very flexible facility that allows
any number of 'kind' parameters and 'nonkind' parameters. A kind
parameter is a constant (fixed at compile time) and may be used for a
kind parameter of a component of intrinsic type. A nonkind parameter is
modelled on the length parameter for type character and may be used for
declaring the bounds of array components. The names of the type
parameters are declared on the type statement of the type definition,
like the dummy arguments of a function or subroutine. Here is an
example for a matrix type

     TYPE matrix(kind,m,n)
         INTEGER, KIND :: kind
         INTEGER, NONKIND :: m,n
         REAL(kind) : element(m,n)
     END TYPE

Explicit values for the type parameters are normally specified when an
object of the type is declared. For example,

     TYPE(matrix(KIND(0.0D0),10,20)) :: a

declares a double-precision matrix of type of size 10 by 20. However,
for a pointer or allocatable object, a colon may be used for a nonkind
to indicate a deferred value; the actual value is determined when the
object is allocated or pointer assigned. For a dummy argument, an
asterisk may be used to indicate an assumed value; the actual value is
taken from the actual argument.

The keyword syntax of procedure calls may be used:

     TYPE(matrix(KIND(0.0),m=10,n=20)) :: a

and the same syntax is used for declaring components of another derived
type.

For enquiries about the values of type parameters, the syntax of
component selection is provided:

     a%kind, a%m

and of course this syntax must not be used to alter the value of a
parameter, say by appearing on the left of an assignment statement.
This syntax is also available for enquiring about a type parameter of
an object of intrinsic type.


2.2 Procedure pointers

A pointer or pointer component may be a procedure pointer. It may have
an explicit or implicit interface and its association with a target is
as for a dummy procedure. As for a dummy procedure, its interface is
neither generic nor elemental. The statement

    PROCEDURE (abstract-interface-name), POINTER :: p => NULL()

declares p to be a procedure pointer initialised as null and with the
explicit interface of abstract-interface-name, which may be the name of
an interface block or a procedure with an explicit interface. As for
data pointers, procedure pointers are either uninitialized or
initialized to null. The statement

    PROCEDURE ( ), POINTER :: p 

declares p to be an uninitialized pointer with an implicit interface.
It may be associated with a subroutine or a function. The statement

    PROCEDURE (TYPE(matrix(KIND(0.0D0),m=10,n=20))), POINTER :: p 

is similar but specifies that the pointer may be associated only with a
function whose result is of the given type.

A function may have a procedure pointer result.

Pointer assignment takes the form

    proc-pointer => proc-target

where proc-pointer is the name of a pointer or the designator of a
pointer component such as a%p and proc-target is the name of a
procedure or a reference to a function whose result is a procedure
pointer.


2.3 Finalization

A derived type may have 'final' subroutines bound to it. Their purpose
is to perform clean-up operations such as the deallocation of pointer
components when an object of the type ceases to exist. Each final
subroutine is a module procedure with a single argument of the derived
type to which will be passed an object that is about to cease to exist.
The usual rules of argument association apply, so the object has the
type and kind type parameters of the dummy argument and has the same
rank unless the subroutine is elemental. The dummy argument is required
not to have INTENT(OUT) and its array shape and nonkind type parameters
are required to be assumed.

An example of the syntax for declaring module subroutines to be final is 

     TYPE T
        : ! Component declarations
     CONTAINS
        FINAL :: finish1, finish2
     END TYPE T

A derived type is finalizable if it has any final subroutines or if it
has a component that is of a type that is finalizable but is neither a
pointer nor allocatable. A nonpointer data object is finalizable if its
type is finalizable.  When such an object ceases to exist, a
finalization subroutine is called for it if there is one with the right
kind type parameters and rank; failing this, an elemental one with the
right kind type parameters is called. Next, each finalizable component
is finalized; if any is an array, each finalizable component of each
element is finalized separately.


2.4 Procedures bound by name to a type

A procedure may be bound to a type and accessed by component selection
syntax from a scalar object of the type rather as if it were a
procedure component with a fixed value.

An example of the syntax is 

     TYPE T
        : ! Component declarations
     CONTAINS
        PROCEDURE :: proc => my_proc
        PROCEDURE :: proc2
     END TYPE T

which binds my_proc with the name proc and proc2 with its own name.
Each procedure must be a module procedure or an external procedure with
an explicit interface. If a is of type T, an example of a type-bound
call is

     CALL a%proc(x,y)

Several such procedures may be accessed by a single generic name. The
PROCEDURE statement is replaced by a GENERIC statement such as

      GENERIC :: gen => proc1, proc2, proc3

The usual rules about disambiguating procedure calls apply to all the
procedures accessible through a single generic binding name.


2.5 The PASS attribute

A procedure that is accessed as a component or by being bound by name
may be given access to the scalar object through which it is invoked by
specifying the PASS attribute:

        PROCEDURE, PASS, POINTER :: p
        PROCEDURE, PASS(arg) :: proc2

By default, the first dummy argument is the passed-object dummy
argument; alternatively, the name of a dummy argument may be given. It
must be a scalar argument of the type, must not be a pointer, must not
be allocatable, and all its nonkind type parameters must be assumed.
When the procedure is invoked through an object, this dummy argument
becomes associated with the object.

The specific procedures of a generic binding may be declared within the
generic statement to be with or without the pass attribute and the
position in the argument list of the passed-on argument can vary, for
example

      GENERIC, PASS :: gen => proc1, proc2
      GENERIC, PASS(arg) :: gen => proc3

This significantly complicates the rules (Section 16.2.3 of the draft
standard) on the required difference between two procedures with the
same generic name. I will not explain the rules here.


2.6 Procedures bound to a type as operators

A procedure may be bound to a type as an operator or a defined
assignment. In this case, the procedure is accessible wherever the type
is accessible. The syntax is through GENERIC statements in the
contained part of a type declaration:

      GENERIC :: OPERATOR(+) => plus1, plus2, plus3
      GENERIC :: ASSIGNMENT(=) => assign1, assign2

There is no restriction on the types of the arguments, although one
expects that one is likely to be of the type to which it is bound. The
usual rules about disambiguating procedure calls apply to all the
procedures accessible in a scoping unit through a single operator.


2.7 Type extension

A derived type may be defined as extensible:

     TYPE, EXTENSIBLE :: matrix(kind,n)
         INTEGER, KIND :: kind
         INTEGER, NONKIND :: n
         REAL(kind) : element(n,n)
     END TYPE

and then extended:

   TYPE, EXTENDS(matrix) :: factored_matrix
         LOGICAL :: factored=.FALSE.
         REAL(matrix%kind) : factors(matrix%n,matrix%n)
   END TYPE 

An extended type is extensible, too, so the term 'parent type' is used
for the type from which an extension is made. All the type parameters,
components, and bound procedures of the parent type are normally
inherited by the extended type and they are known by the same names.
For example,

    TYPE(factored_matrix(kind(0.0),10)) :: f

declares a real factored matrix of order 10. The values of its type
parameters are given by f%kind and f%n. The inherited component may be
referenced as f%element.

In addition, the extended type has the parameters, components, and
bound procedures that are declared in its own definition. Here, we have
the additional components f%factored and f%factors.

The extended type also has a component, called the parent component,
whose type and type parameters are those of its parent type and whose
name is the name of the parent type. Here, the parent component was
needed in the type definition.  The inherited parameters, components,
and bound procedures may be accessed directly, f%n and f%element, or
through the parent component, f%matrix%n and f%matrix%element.

The parent component and may be given a default initial value in the
TYPE statement:

   TYPE, EXTENDS(matrix=matrix(kind(0.0),10)(0.0)) :: factored_matrix

This overrides any default initialisation defined for the parent type's 
components. 

There is an ordering of the nonparent components that is needed in
structure constructors and for input-output. It consists of the
inherited components in the order of the parent type, followed by the
new components.

In a structure constructor, values may be given for a parent component
or for the inherited components. No component may be explicitly
specified more than once and any component that does not have a default
value must be specified exactly once.

A specific procedure bound by name is permitted to have the name and
attributes of a procedure bound to the parent, apart from the type of
the PASS argument, if any. It must be not PRIVATE if the parent's
binding is PUBLIC. In this case, it overrides the procedure bound to
the parent type.

Similarly, a procedure bound as a specific within a generic may be
overridden if it is given the same generic name or operator and would
have been overridden had it been bound as a specific.

Such overridding may be prohibited in the parent type:

      PROCEDURE, NON_OVERRIDABLE :: proc2
      GENERIC, PASS, NON_OVERRIDABLE :: gen => proc1, proc2

A further possibility is that the binding may be deferred:

      PROCEDURE (proc) :: proc2 => null()
      GENERIC (genr) :: gen => null()

Here proc and genr are the names of specific and generic interfaces for
which there are no actual procedures (yet). Now overridding is required,
though it may be deferred again. 


2.8 Polymorphic entities

A polymorphic entity is declared to be of a certain type by using the
CLASS keyword in place of the TYPE keyword and is able to take this
type or any of its extensions during execution. The type at a
particular point of the execution is called the dynamic type. The
feature allows code to be written for objects of a given type and used
later for objects of this type and of any extension of it.  An entity
is said to be 'type compatible' with entities of the same declared type
or of any declared type that is an extension of its declared type.

Intrinsic assignment is extended; the left-hand side variable is not
permitted to be polymorphic, but the right-hand side may have any
dynamic type with which the left-hand side is type compatible.

Access is permitted directly to type parameters, components, and bound
procedures for the declared type only. However, intrinsic assignment
provides indirect access to them. Another way is through the SELECT
TYPE construct:

    CLASS (matrix(kind(0.0),10)) :: f
      :
    SELECT TYPE ff => f
       TYPE IS (matrix)
          : ! Block of statements
       TYPE IS (factored_matrix)
          : ! Block of statements
    END SELECT 

The first block is executed if the dynamic type of f is matrix and the
second block is executed if it is factored_matrix. In the second block,
we may use the associated name ff to access the extensions thus:
ff%factored, ff%factor. This construct is described in detail in
section 2.9.

An object may be declared with the CLASS(*) specifier and is then
'unlimited polymorphic'. It is not type compatible with any other
CLASS(*) object, but is compatible with all entities of extensible
type.


2.9 ASSOCIATE and SELECT TYPE constructs

To be written.



3. MISCELLANEOUS ENHANCEMENTS

3.1 Structure constructors

The value list of a structure constructor may use the syntax of an
actual argument list with keywords that are component names. Components
that were given default values in the type definition may be omitted.
Of course, no component may be given an explicit value more than once
and explicit values override default values. If the type has
parameters, these must be specified:

    a = TYPE(matrix(KIND(0.0),m=10,n=20)) (element = 0.0)
    

3.2 The allocate statement

The allocatable attribute is no longer restricted to arrays and a
source variable may be specified to provide values for deferred nonkind
type parameters and an initial value for the object itself. For
example,

    TYPE(matrix(KIND(0.0D0),m=:,n=:)),ALLOCATABLE :: b, c
    ALLOCATE(b,SOURCE=a)
    ALLOCATE(c,SOURCE=a)

allocates the scalar objects b and c to be 10 x 20 matrices with the
value of a.  With source present, the allocate statement allocates just
one object. The value is assigned by the rules for intrinsic
assignment; in particular, the rules of array conformability apply so
that the source variable is limited to being a scalar or an array of
the same shape as the arrays being allocated.

Alternatively, the nonkind type parameters may be specified by a type
declaration within the allocate statement:

    ALLOCATE(TYPE(matrix(KIND(0.0D0),m=10,n=20)) :: b,c)

If this feature is used in an allocate statement, initialisation from a
source variable is not available. One or other must be used if the type
has any deferred type parameters. If either is used, each allocatable
object in the list must have the same non-deferred type parameters as
the source variable or the type declaration.

The allocate statement may also specify the dynamic type of a polymorphic
object: 

    ALLOCATE(TYPE(factored_matrix(kind(0.0),10)) :: b,c)
    ALLOCATE(d,SOURCE=a) ! d takes its dynamic type from a

Each allocated object must be type compatible with the type specified type.

An ALLOCATE or DEALLOCATE statement may optionally contain an ERRMSG=
specifier that identifies a default character scalar variable.  If an
error condition occurs during execution of the statement, the processor
assigns an explanatory message to the variable. If no such condition
occurs, the value of the variable is not changed.


3.3 More control of access from a module

More detailed control of access from a module is possible. The
individual components of a derived type may be declared PUBLIC or
PRIVATE:

   TYPE, EXTENDS(PRIVATE::person) :: s_person ! Parent component is private
   CHARACTER(:), ALLOCATABLE, PUBLIC :: name
   INTEGER, PRIVATE :: age

The bindings to a type may be declared PUBLIC or PRIVATE:

   PROCEDURE, PUBLIC, PASS, POINTER :: p
   GENERIC, PUBLIC, PASS :: gen => proc1, proc2
   GENERIC, PRIVATE :: OPERATOR(+) => plus1, plus2, plus3

Note, however, that a final subroutine is always public. 

The PROTECTED attribute imposes limitations on the usage of a module
entity.  The PROTECTED statement has the syntax

     PROTECTED [ :: ] entity-name-list

and it may be specified in a type declaration statement such as 

    REAL, PROTECTED :: a(10)

If it is not a pointer, the protected entity is definable only within
the module in which it is declared.  If a pointer, its association
status may change only within the module in which it is declared. If an
object has the PROTECTED attribute, all of its subobjects have the
PROTECTED attribute.


3.4 Pointer assignment

Pointer assignment for arrays has been extended to allow lower bounds
to be specified:

      p(0:,0:) => a

As for dummy arrays, the lower bounds may be specification expressions.

Remapping of the elements of a rank-one array is permitted: 

      p(1:m,1:2*m) => a(1:2*m*m)

The mapping is in array-element order and the target array must be
large enough.  The bounds may be specification expressions.

If the target of a pointer assignment is polymorphic, the pointer must
he polymorphic and type compatible with it. It takes the dynamic type
of the target.

Nonkind type parameters of the pointer may be deferred (declared with a
colon).  Pointer assignment gives these the values of the corresponding
parameters of the target. All its other type parameters must have the
same values as the corresponding type parameters of the target (but the
target may have additional type parameters).


3.5 The VOLATILE attribute

The VOLATILE attribute has been introduced for a data object to
indicate that its value might change by means not specified in the
standard, for example, by another program executing in parallel. Like
the ASYNCHRONOUS attribute, whether an object has the VOLATILE
attribute may varying between scoping units.  If an object has the
VOLATILE attribute, all of its subobjects also have the attribute.

The effect is that the compiler is required to reference and define the
memory that can change by other means rather than rely on values in
cache or other temporary memory.


3.6 The IMPORT statement

The IMPORT statement has the syntax

     IMPORT [[ :: ] import-name-list ]

and is allowed only in an interface body. It specifies that all
entities in the host scoping unit, or those named, are accessible by
host association.


3.7 Access to the computing environment

The concept of a module being intrinsic was introduced as part of the 
exception handling technical report (Reid 2001). A new intrisic module
is ISO_FORTRAN_ENV. It contains the following constants

INPUT_UNIT is a default integer scalar holding the unit identified by an
    asterisk in a READ statement.

OUTPUT_UNIT is a default integer scalar holding the unit identified by an
    asterisk in a WRITE statement.

ERROR_UNIT is a default integer scalar holding the unit used for the
    purpose of error reporting. THE VALUE may be the same as that of
    OUTPUT_UNIT.

IOSTAT_END is a default integer scalar holding the value that is
    assigned to the IOSTAT= variable if an end-of-file condition occurs
    during execution of an input/output statement and no error
    condition occurs. This value is negative.

IOSTAT_EOR is a default integer scalar holding the value that is
    assigned to the IOSTAT= variable if an end-of-record condition
    occurs during execution of an input/output statement and no
    end-of-file or error condition occurs. This value is negative.

In addition, the following intrinsic procedures have been added. Note
that they are ordinary intrinsics and are not part of the module
ISO_FORTRAN_ENV.

COMMAND_ARGUMENT_COUNT () is an inquiry function that returns a default
   integer scalar.  The value is equal to the number of command
   arguments available.  If there are no command arguments available or
   if the processor does not support command arguments, the value is 0.
   If the processor has a concept of a command name, the command name
   does not count as one of the command arguments.

CALL GET_COMMAND ([COMMAND,LENGTH, STATUS]) returns entire command by which
   the program was invoked in the following optional INTENT(OUT) arguments

   COMMAND is a default character scalar. It is assigned the entire
      command by which the program was invoked. If the command cannot be
      determined, it is assigned all blanks.

   LENGTH is a default integer scalar. It is assigned the significant 
      length of the command by which the program was invoked. This may
      include trailing blanks if the processor allows commands with
      significant trailing blanks. If the command length cannot be
      determined, 0 is assigned.

   STATUS is a default integer scalar. It is assigned the value -1 if
      the COMMAND argument is present and has a length less than the
      significant length of the command. It is assigned a
      processor-dependent positive value if the command retrieval
      fails. Otherwise, 0 is assigned.

CALL GET_COMMAND_ARGUMENT (NUMBER [, VALUE, LENGTH, STATUS]) returns a
   command argument.

   NUMBER is a default integer INTENT(IN) scalar. It identifies
      the required command argument. Useful values are those between 0
      and COMMAND_ARGUMENT_COUNT (). Other values are allowed, but will
      result in error status return (see below). Command argument 0 is
      the command name by which the program was invoked if the
      processor has such a concept.

   VALUE is a default character INTENT(OUT) scalar. It is assigned the
      value of the command argument specified by NUMBER. If the command
      argument value cannot be determined, VALUE is assigned all
      blanks.

   LENGTH is a default integer INTENT(OUT) scalar. It is assigned 
      the significant length of the command argument specified by
      NUMBER. This may include trailing blanks if the processor allows
      command arguments with significant trailing blanks. If the
      command argument length cannot be determined, a length of 0 is
      assigned.

   STATUS is a default integer INTENT(OUT) scalar. It is assigned
      the value -1 if the VALUE argument is present and has a length
      less than the significant length of the command argument
      specified by NUMBER. It is assigned a processor-dependent
      positive value if the argument retrieval fails. Otherwise, it is
      assigned the value 0.


CALL GET ENVIRONMENT_VARIABLE (NAME [, VALUE, LENGTH, STATUS, TRIM NAME])   
           Obtain the value of an environment variable

   NAME is a default character INTENT(IN) scalar. The interpretation of
      case is processor dependent

   VALUE is a default character INTENT(OUT) scalar. It is assigned the
      value of the environment variable specified by NAME. VALUE is
      assigned all blanks if the environment variable does not exist or
      does not have a value or if the processor does not support
      environment variables.

   LENGTH is a default integer INTENT(OUT) scalar. If the specified
      environment variable exists and has a value, LENGTH is set to the
      length of that value. Otherwise LENGTH is set to 0.

   STATUS  is a default integer INTENT(OUT) scalar. If the environment
      variable exists and either has no value or its value is
      successfully assigned to VALUE, STATUS is set to zero. STATUS is
      set to -1 if the VALUE argument is present and has a length less
      than the significant length of the environment variable. It is
      assigned the value 1 if the specified environment variable does
      not exist, or 2 if the processor does not support environment
      variables. Processor-dependent values greater than 2 may be
      returned for other error conditions.

   TRIM_NAME is a logical INTENT(IN) scalar. If it is present with the
      value false then trailing blanks in NAME are considered significant
      if the processor supports trailing blanks in environment variable
      names. Otherwise trailing blanks in NAME are not considered part of
      the environment variable's name.


3.8 Support for international character sets

Fortran 95 introduced the possibility of multi-byte character sets,
which provides a foundation for supporting ISO 10646 (2000). This is a
standard for 4-byte characters, which is wide enough to support all the
world's languages. A new intrinsic function has been introduced:

   SELECTED_CHAR_KIND(NAME)

NAME is a scalar of type default character. If it has the value
   DEFAULT, the kind value for default character type is returned.  If it
   has the value ASCII and ASCII (1991) is supported, its kind value is
   returned.  If it has the value ISO_10646 and ISO 10646 (2000) is
   supported, its kind value is returned.  If another character kind is
   supported, its name may be given and its kind will be returned.
   In all other cases, the value -1 is returned.


3.9. Number of continuation lines

Up to 99 continuation lines are allowed. 


3.10. Binary, octal and hex constants

A binary, octal and hex constant is permitted for a principal argument
in a call of the intrinsic function INT, REAL, CMPLX, or DBLE, that is,
not for the optional argument that specifies the kind of the result.

For INT, it is treated as if it were an integer constant of the kind
with the largest decimal exponent range supported by the processor.

For the others, it is treated as having the value that a variable of
the same type and kind type parameters as the result would have if its
value was the bit pattern specified. The interpretation of the value of
the bit pattern is processor dependent. If the kind is not specified, it
is the default kind.


3.11 Array constructor syntax

Square brackets are permitted as an alternative to '(/' and '/)' for
delimiters for array constructors. 

3.12 Specification and initialization expressions

The rules on what may appear in a specification or an initialization
expression have been relaxed, but remain very complicated. I will not
attempt to summarize them here. For details, see 7.1.6 and 7.1.7 of J3
(2002).


4. INPUT/OUTPUT ENHANCEMENTS

4.1 Derived type input/output

It may be arranged that when a derived-type object is encountered in an
input- output list, a Fortran subroutine is called. This reads some
characters from the file and constructs a value of the derived type or
accepts a value of the derived type and writes some characters to the
file.

For formatted io, the DT edit descriptor passes a character string and
an integer array to control the action. An example is

     DT 'linked-list' (10, -4, 2)

The character string may be omitted, in which case a string of length
zero is passed. The bracketed list of integers may be omitted, in which
case an array of length zero is passed.

The subroutines must be bound to the type as generic bindings (see
sections 2.4 and 2.6) of the form

      GENERIC :: READ(FORMATTED) => r1, r2
      GENERIC :: READ(UNFORMATTED) => r3, r4, r5
      GENERIC :: WRITE(FORMATTED) => w1
      GENERIC :: WRITE(UNFORMATTED) => w2, w3

which makes them accessible wherever the type is accessible. 

The form of such a subroutine depends on whether it is for formatted or 
unformatted input or output:

  SUBROUTINE formatted_io  (unit,dtv,iotype,v_list,iostat,iomsg)
  SUBROUTINE unformatted_io(unit,dtv,              iostat,iomsg)

unit is a scalar of intent(in) and type default integer. Its value is
     the unit on which input-output is taking place or zero if on an
     internal file.

dtv is a scalar of the derived type. It must be polymorphic if and only
     if the object in the io list is polymorphic. Any nonkind type
     parameters must be assumed. For output, it is of intent(in) and
     holds the value to be written.  For input, it is of intent(out)
     and must be set to the value read.

iotype is a scalar of intent(in) and type CHARACTER(*). Its value is
     the character string from the edit descriptor.

v_list is a rank-one assumed-shape array of type default integer. Its
     value comes from the bracketed list of the edit descriptor.

iostat is a scalar of intent(out) and type default integer. If an error
     condition occurs, it must be given a positive value. Otherwise, if
     an end-of-file or end-of-record condition occurs it must be given
     the value IOSTAT_END or IOSTAT_EOR (see 3.7), respectively.
     Otherwise, it must be given the value zero.

iomsg is a scalar of intent(inout) and type CHARACTER(*). If iostat is
     given a nonzero value, iomsg must be set to an explanatory
     message.  Otherwise, it must not be altered.

Input-output within the subroutine to external files is limited to the
specified unit and in the specified direction. However, io to an
internal file is permitted.

The file position on entry is treated as a left tab limit and there is
no record termination on return.


4.2 Asynchronous input/output

Input/output may be asynchronous, that is, other statements may execute
while an i/o statement is in execution. It is permitted only for
external files opened with ASYNCHRONOUS = 'YES' in the OPEN statement
and is indicated by ASYNCHRONOUS = 'YES' in the READ or WRITE
statement. Execution of an asynchronous i/o statement initiates a
'pending' i/o operation, which is terminated by a wait operation for
the file. This may be performed by an explicit wait statement

     WAIT(10)

or implicitly by an INQUIRE, CLOSE, or file positioning statement for
the file.  The compiler is permitted to treat each asynchronous i/o
statement as an ordinary i/o statement; this, after all, is just the
limiting case of the i/o being fast. The compiler is, of course,
required to recognize all the new syntax.

Further asynchronous i/o statements may be executed for the file before
the wait statement is reached. The i/o statements are performed in the
same order as if they were synchronous.

An execution of an asynchronous i/o statement may be identified by a
scalar integer variable in an ID= specifier. Successful execution of
the statement causes the variable to be given a processor-dependent
value which can be passed to a subsequent WAIT or INQUIRE statement as
a scalar integer variable in an ID= specifier.

A wait statement may have END=, EOR=, ERR= and IOSTAT= specifiers.
These have the same meanings as for an i/o statement and refer to
situations that occur while the i/o operation is pending. If there is
an ID= specifier, too, only the identified pending operation is
terminated and the other specifiers refer to this; otherwise, all
pending operations for the file are terminated in turn.

An INQUIRE statement is permitted to have a PENDING= specifier for a
scalar default logical variable. If an ID= specifier is present, the
variable is given the value true if the particular i/o operation is
still pending and false otherwise.  If no ID= specifier is present, the
variable is given the value true if all i/o operations for the unit are
still pending and false otherwise. In the 'false' case, wait operations
are performed for the file or files. Wait operations are not performed
in the 'true' case, even if some of the i/o operations are complete.

A file positioning statement (BACKSPACE, ENDFILE, REWIND) performs wait
operations for all pending i/o operations for the file.

Asynchronous i/o is not permitted in conjunction with user-defined
derived type i/o (section 4.1).

A variable in a scoping unit is said to be an 'affector' of a pending
i/o operation if any part of it is associated with any part of an item
in the i/o list, namelist, or SIZE= specifier. While an i/o operation
is pending, an affector is not permitted to be redefined, become
undefined, or have its pointer association status changed. While an
input i/o operation is pending, an affector is also not permitted to be
referenced or associated with a dummy argument with the VALUE attribute
(section 5.6).

The ASYNCHRONOUS attribute has been introduced to warn the compiler
that some code motions across wait statements might lead to incorrect
results. If a variable appears in an executable statement or a
specification expression in a scoping unit and any statement of the
scoping unit is executed while the variable is an affector, it must
have the ASYNCHRONOUS attribute in the scoping unit.

A variable is automatically given the attribute if it or a subobject of
it is an item in the i/o list, namelist, or SIZE= specifier of an
asynchronous i/o statement. A named variable may be declared with this
attribute:

    INTEGER, ASYNCHRONOUS :: int_array(10)

or given it by the ASYNCHRONOUS statement

    ASYNCHRONOUS :: int_array, another

This statement may be used to give the attribute to a variable that is
accessed by use or host association.

All subobjects of a variable with the ASYNCHRONOUS attribute have the
attribute.

An actual argument that is a data object and the corresponding dummy
argument must both have the ASYNCHRONOUS attribute or both not have
it.


4.3 FLUSH statement

Execution of a FLUSH statement for an external file causes data written
to it to be available to other processes, or causes data placed in it
by means other than Fortran to be available to a read statement. The 
syntax is just like that of the file positioning statements. 


4.4 IOMSG specifier

Any of the IO statements that have ERR= and IOSTAT= specifiers are
permitted to have an IOMSG= specifier. This identifies a scalar
variable of type default character into which the processor places a
message if an error, end-of-file, or end-of-record condition occurs
during execution of the statement.


4.5 Stream access input/output

Stream access is a new method of accessing an external file. It is 
established by specifying ACCESS='STREAM' on the OPEN statement may be 
formatted or unformatted. 

The file is positioned by 'file storage units', normally bytes,
starting at position 1.  The current position may be determined from a
scalar integer variable is a POS= specifier of an INQUIRE statement for
the unit.  A required position may be indicated in a READ or WRITE
statement by the POS= specifier which accepts a scalar integer
expression. For formatted i/o, the value must be 1 or one previously
returned in an INQUIRE statement for the file. In the absence of a POS=
specifier, the file position is left unchanged.

The standard permits a processor to prohibit the use of POS= for
particular files that do not have the properties necessary to support
random positioning or its use for forward positioning if the file does not
have the properties necessary to support this.


4.6 ROUND= specifier

Rounding during formatted i/o may be controlled by the ROUND= specifier
on the OPEN statement, which takes one of the values UP, DOWN, ZERO,
NEAREST, COMPATIBLE, or PROCESSOR_DEFINED. It may be overridden by a
ROUND= specifier in a READ or WRITE statement with one of these
values.  The meanings are obvious except for the difference between
NEAREST and COMPATIBLE. Both refer to a closest representable value. If
two are equidistant, which is taken is processor dependent for NEAREST
and the value away from zero for COMPATIBLE.

The rounding mode may also be temporarily changed within a READ or WRITE
statement by the RU, RD, RZ, RN, RC, and RP edit descriptors.


4.7 DECIMAL= specifier

The character that separates the parts of a decimal number in formatted
i/o may be controlled by the DECIMAL= specifier on the OPEN statement,
which takes one of the values COMMA or POINT. It may be overridden by a
DECIMAL= specifier in a READ or WRITE statement with one of these
values. The meanings are obvious.

The mode may also be tempoprarily changed within a READ or WRITE
statement by the DC and DP edit descriptors.


4.8 SIGN= specifier

The SIGN= specifier has been added to the OPEN statement. It can take
the value SUPPRESS, PLUS, or PROCESSOR_DEFINED and controls the
optional plus characters in formatted numeric output. It may be
overridden by a ROUND= specifier in a WRITE statement with one of these
values. The rounding mode may also be tempoprarily changed within a
WRITE statement by the SS, SP, and S edit descriptors, which were part
of Fortran 95.



5 INTEROPERABILITY WITH C

5.1 Introduction

Fortran 2000 provides a standardized mechanism for interoperating with
C.  Clearly, any entity involved must be such that equivalent
declarations of it may be made in the two languages. This is enforced
within the Fortran program by requiring all such entities to be
'interoperable'.  We will explain in turn what this requires for types,
variables, and procedures. They are all requirements on the syntax so
that the compiler knows at compile time whether an entity is
interoperable. We finish with two examples.


5.2 Interoperability of intrinsic types

There is an intrinsic module called ISO_C_BINDING that contains named
constants holding kind type parameter values for intrinsic types. Their
names are shown in Table 1, together with the corresponding C types.
The processor is not required to support all of them. Lack of support
is indicated with a negative value.  

   Table 1. Interoperability between Fortran and C types

 Type      Named constant       C type or types

 INTEGER   C_INT               int, signed int
           C_SHORT             short int, signed short int
           C_LONG              long int, signed long int
           C_LONG_LONG         long long int, signed long long int
           C_SIGNED_CHAR       signed char, unsigned char
           C_SIZE_T            size_t
           C_INT_LEAST8_T      int_least8_t
           C_INT_LEAST16_T     int_least16_t
           C_INT_LEAST32_T     int_least32_t
           C_INT_LEAST64_T     int_least64_t
           C_INT_FAST8_T       int_fast8_t
           C_INT_FAST16_T      int_fast16_t
           C_INT_FAST32_T      int_fast32_t
           C_INT_FAST64_T      int_fast64_t
           C_INTMAX_T          c intmax_t
                                                 
 REAL      C_FLOAT             float, float _Imaginary
           C_DOUBLE            double, double _Imaginary

 COMPLEX   C_LONG_DOUBLE       long double, long double _Imaginary
           C_COMPLEX           _Complex
           C_DOUBLE_COMPLEX    double _Complex
           C_LONG_DOUBLE_COMPLEX long double _Complex

 LOGICAL   C_BOOL              _Bool

 CHARACTER C_CHAR              char


For character, interoperability also requires that the length type
parameter be omitted or be specified by an initialization expression
whose value is one. The following named constants (with the obvious
meanings) are provided:  C_NULL_CHAR, C_ALERT, C_BACKSPACE, 
C_FORM_FEED,
C_NEW_LINE, C_CARRIAGE_RETURN, C_HORIZONTAL_TAB, C_VERTICAL_TAB.


5.3 Interoperability with C pointers

For interoperating with C pointers (which are just addresses), the
module contains a derived type C_PTR that is interoperable with any C
pointer type and a named constant C_NULL_PTR with the value NULL of C.

The module also contains the following procedures:

C_LOC (X) is an inquiry function that returns the C address of X.
   X is permitted to be a procedure that is interoperable (see para.
   5) or a variable that has the TARGET attribute and is either
   interoperable or is an allocated allocatable variable that has
   interoperable type and type parameters.

C_ASSOCIATED (C_PTR1[, C_PTR2]) is an inquiry function that returns 
   a default logical scalar. It has the value false if C_PTR1 is a C
   null pointer or if C_PTR2 is present with a different value;
   otherwise, it has the value true.

C_F_POINTER (CPTR, FPTR [, SHAPE])) is a subroutine with arguments

   CPTR is a scalar of type C_PTR with intent IN. Its value is the
      C address of an entity that is is interoperable with variables of
      the type and type parameters of FPTR. It shall not be the C
      address of a Fortran variable that does not have the TARGET
      attribute.

   FPTR is a pointer that becomes pointer associated with the target of
      CPTR. If it is an array, its shape is specified by SHAPE.

   SHAPE (optional) is a rank-one array of type integer with intent
      IN. If  present, its size is equal to the rank of FPTR. If FPTR
      is an array, it must be present.

This is the mechanism for passing dynamic arrays between the languages.
A Fortran pointer or assumed-shape array cannot be passed to C since
its elements need not be contiguous in memory. However, an allocated
allocatable array may be passed to C and an array allocated in C may be
associated with a Fortran pointer.


5.4 Interoperability of derived types

For a derived type to be interoperable, it must be given the BIND
attribute explicitly:

      TYPE, BIND(C) :: MYTYPE
       :
      END TYPE MYTYPE

Each component must have interoperable type and type parameters,
must not be a pointer, and must not be allocatable. This allows
Fortran and C types to correspond, for example

         typedef struct {
           int m, n;
           float r;
         } myctype

is interoperable with

         USE ISO_C_BINDING
         TYPE, BIND(C) :: MYFTYPE
           INTEGER(C_INT) :: I, J
           REAL(C_FLOAT) :: S
         END TYPE MYFTYPE

The name of the type and the names of the components are not
significant for interoperability.

No Fortran type is interoperable with a C union type, struct type that
contains a bit field, or struct type that contains a flexible array
member.


5.5 Interoperability of variables

A scalar Fortran variable is interoperable if it is of interoperable
type and type parameters, and is neither a pointer nor allocatable.

An array Fortran variable is interoperable if it is of interoperable
type and type parameters, and is of explicit shape or assumed size. It
interoperates with a C array of the same type types parameters and
shape, but with reversal of subscripts. For example, a Fortran array
declared as

             INTEGER :: A(18, 3:7, *)

is interoperable with a C array declared as

             int b[][5][18]


5.6 Interoperability of procedures

For the sake of interoperability, a new attribute, VALUE, has been
introduced for scalar dummy arguments. When the procedure is called, a
copy of the actual argument is made. The dummy argument is a variable
that may be altered during execution of the procedure, but on return no
copy back takes place. If the type is character, the character length
must be one.

A Fortran procedure is interoperable if it has an explicit interface
and is declared with the BIND attribute:

        FUNCTION FUNC(I, J, K, L, M), BIND(C)

All the dummy arguments must be interoperable. For a function, the
result must be scalar and interoperable. The procedure has a 'binding
label', which has global scope and is the name by which it is known to
the C processor. By default, it is the lower-case version of the
Fortran name. For example, the above function has the binding label
'func'. Another binding label may be specied:

        FUNCTION FUNC(I, J, K, L, M), BIND(C, NAME='C_Func')

Such a procedure corresponds to a C function prototype with the same
binding label. For a function, the result must be interoperable.  For a
subroutine, the prototype must have a void result. A dummy argument
with the VALUE attribute must correspond to formal parameter of the
prototype that is not of a pointer type.  A dummy argument without the
VALUE attribute must correspond to formal parameter of the prototype
that is of a pointer type.


5.7 Interoperability of global data

An interoperable module variable or a common block with interoperable
members may be given the BIND attribute:

           USE ISO_C_BINDING
           INTEGER(C_INT), BIND(C) :: C_EXTERN
           INTEGER(C_LONG) :: C2
           BIND(C, NAME='myVariable') :: C2
           COMMON /COM/ R, S
           REAL(C_FLOAT) :: R, S
           BIND(C) :: /COM/

It has a binding label defined by the same rules as for procedures
and interoperate with a C variable of a corresponding struct type.


5.8 Example of Fortran calling C

C Function Prototype:

  int C_Library_Function(void* sendbuf, int sendcount, int *recvcounts)

Fortran Module:

          MODULE FTN_C
             INTERFACE
                INTEGER (C_INT) FUNCTION C_LIBRARY_FUNCTION    &
                   (SENDBUF, SENDCOUNT, RECVCOUNTS), &
                   BIND(C, NAME='C_Library_Function')
                   USE ISO_C_BINDING
                   IMPLICIT NONE
                   TYPE (C_PTR), VALUE :: SENDBUF
                   INTEGER (C_INT), VALUE :: SENDCOUNT
                   TYPE (C_PTR), VALUE :: RECVCOUNTS
                END FUNCTION C_LIBRARY_FUNCTION
             END INTERFACE
          END MODULE FTN_C


Fortran Calling Sequence:


         USE ISO_C_BINDING, ONLY: C_INT, C_FLOAT, C_LOC
         USE FTN_C
         ...
         REAL (C_FLOAT), TARGET :: SEND(100)
         INTEGER (C_INT)        :: SENDCOUNT
         INTEGER (C_INT), ALLOCATABLE, TARGET :: RECVCOUNTS(:)
          ...
         ALLOCATE( RECVCOUNTS(100) )
          ...
         CALL C_LIBRARY_FUNCTION(C_LOC(SEND), SENDCOUNT, &
            C_LOC(RECVCOUNTS))
         ...


5.9 Example of C calling Fortran

Fortran Code:

 SUBROUTINE SIMULATION(ALPHA, BETA, GAMMA, DELTA, ARRAYS), BIND(C)
      USE ISO_C_BINDING
      IMPLICIT NONE
      INTEGER (C_LONG), VALUE                 :: ALPHA
      REAL (C_DOUBLE), INTENT(INOUT)          :: BETA
      INTEGER (C_LONG), INTENT(OUT)           :: GAMMA
      REAL (C_DOUBLE),DIMENSION(*),INTENT(IN) :: DELTA
      TYPE, BIND(C) :: PASS
           INTEGER (C_INT) :: LENC, LENF
           TYPE (C_PTR)    :: C, F
      END TYPE PASS
      TYPE (PASS), INTENT(INOUT) :: ARRAYS
      REAL (C_FLOAT), ALLOCATABLE, TARGET, SAVE :: ETA(:)
      REAL (C_FLOAT), POINTER :: C_ARRAY(:)
      ...
      ! Associate C_ARRAY with an array allocated in C
      CALL C_F_POINTER (ARRAYS%C, C_ARRAY, (/ARRAYS%LENC/) )
      ...
      ! Allocate an array and make it available in C
      ARRAYS%LENF = 100
      ALLOCATE (ETA(ARRAYS%LENF))
      ARRAYS%F = C_LOC(ETA)
      ...
 END SUBROUTINE SIMULATION


C Struct Declaration

         struct pass {int lenc, lenf; float* f, *c}


C Function Prototype:

         void simulation(long alpha, double *beta, long *gamma,
            double delta[], struct pass *arrays)


C Calling Sequence:

         simulation(alpha, &beta, &gamma, delta, &arrays);





REFERENCES

ASCII (1991) ISO/IEC 646:1991, Information technology - ISO 7-bit coded
    character set for information interchange.  ISO, Geneva.

Cohen, Malcolm (ed.) (2001)  ISO/IEC TR 15581(E) Technical Report:
    Information  technology - Programming languages - Fortran -
    Enhanced data type facilities (second edition). ISO, Geneva.

ISO 10646 (2000) ISO/IEC 10646-1:2000, Information technology - Universal
    multiple-octet coded character set (UCS) - Part 1: Architecture and
    basic multilingual plane. ISO, Geneva.

J3 (2002). J3/02-007R3 - Draft Fortran standard. Also known as 
    ISO/IEC JTC1/SC22/WG5 N14xx.  Available as PS, PDF, or text from
    ftp://ftp.j3-fortran.org/j3/doc/standing/007/

Metcalf, Michael and Reid, John (1999). Fortran 90/95 explained (second
   edition).  Oxford University Press.

Reid, John (ed.) (2001)  ISO/IEC TR 15580(E) Technical Report:
    Information  technology - Programming languages - Fortran -
    Floating-point exception handling (second edition). ISO, Geneva.


