From owner-sc22wg5  Mon Jul 23 19:45:24 2001
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 TAA98784
	for <SC22WG5@dkuug.dk>; Mon, 23 Jul 2001 19:45:23 +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 SAA29428;
	Mon, 23 Jul 2001 18:45:22 +0100
Received: (from jkr@localhost)
	by jkr.cc.rl.ac.uk (8.8.8+Sun/8.8.8) id SAA13773;
	Mon, 23 Jul 2001 18:47:33 +0100 (BST)
Date: Mon, 23 Jul 2001 18:47:33 +0100 (BST)
From: John Reid <jkr@rl.ac.uk>
Message-Id: <200107231747.SAA13773@jkr.cc.rl.ac.uk>
To: SC22WG5@dkuug.dk
Subject: Dynamic arrays and interfacing with C
Cc: donev@pa.msu.edu
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"

WG5,
    
Here is a draft of a paper that I have prepared with the help of
Aleksandar Donev for the London meeting in the context of review the
current draft F2000 standard.

Comments, please. 

John. 


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



             Dynamic arrays and interfacing with C

                John Reid and Aleksandar Donev


Disclaimer: John would like to make it clear that he is writing this
paper as an individual and not as Convener.


1. INTRODUCTION

We are writing this paper because of our belief that the present
proposal for interoperability with C (J3/01-007R2, section 15) has a
serious deficiency. It is impossible for a Fortran procedure, while
being called from C, to allocate an array and make that array available
to the C code. Conversely, it is impossible for a C function, while
being called from Fortran, to allocate an array and make that array
available to the Fortran code.

We have both found a need for this feature within our workplaces.
John has colleagues who call Fortran from C extensively and wish to
be able to use structures with allocatable components to hold the
data pertinent to each particular problem. Aleksandar often interfaces
with C graph and sparse-matrix libraries, which return results
in the form of dynamic C arrays, that also need to be used in Fortran.

It is our belief that if this requirement is not addressed now,
there will be a strong request for it next year when the draft is
sent out for public comment.

We propose a simple way to do this here. It also has the side
benefit of providing a dynamic array within Fortran that has far
less storage overheads than allocatable or pointer arrays.


2. THE MOVABLE ARRAY

Our starting point is the assumed-size array, which is already
interoperable with C provided its rank is one. We call our new
sort of array 'movable' for the moment. We are not committed to
this adjective, but we want to avoid 'pointer' since this is
already used extensively in the standard with another meaning.
A movable array can be moved from one target to another with the
pointer assignment statement:

   real, movable :: a(*)
   real, target  :: t(100)
   a => t

and allocated and deallocated:

   allocate (a(30))
   deallocate (a)

We do not want any array copying to take place with such a pointer
assignment, so the right-hand side must be an array that is movable,
assumed-size, allocatable, or explicit-size. It must have the same type
and must have the target attribute. An element of such an array is
allowed, too (as for the actual argument corresponding to an
assumed-size dummy array). The ranks are not required to agree (again,
as for the actual argument corresponding to an assumed-size dummy
array), and in such cases array element sequence association
between the target and the movable array is implied.

Deallocation will be allowed only if the target was allocated as a
movable array.

Movable arrays can also be null, tested for null, and tested for
being associated with the same target:

   real, movable :: a(*), b(*)=>null(), c(*)
    ...
   a => null()
   nullify(c)
   if (associated(b)) then
    ...
   if (associated(a,b)) then

The two-argument version tests only that a and b share the same
first element.

We expect the implementation of a movable array to be like that for an
assumed-size array. Mostly, its descriptor will consist of an address
only.  However, a debugging compiler might also hold its size and a
flag to indicate whether the target was allocated as a movable array.

An explicit interface will not be required. If the dummy argument is
a movable array, the actual argument must be a movable array. If the
actual argument is a movable array, the dummy argument must be a movable,
explicit-shape or assumed-size array; the calling program passes the
descriptor and receives it on return.

We will also permit movable arrays as components of types:

   type my_data
      real, movable :: a(*) => null()
   end type my_data

and we permit multi-rank movable arrays:

   subroutine mine(lda)
   integer :: lda
   real, movable :: a(lda,*)

   type my_data
      integer :: lda
      real, movable :: a(lda,*)
   end type my_data

The bounds must be defined whenever a movable array is referenced and
must not be altered while a movable array is associated with a target.
If a multi-rank movable array is a component of a type, the bounds of
its leading extents must be integer expressions depending only on other
components of the type.

For the sake of optimization, we propose that the rules that apply to
assumed-size arrays with respect to aliasing should apply also to
movable arrays. While a movable array is associated with a target,
action that affects value of the target must be taken through the
movable array.


3. INTEROPERABILITY WITH C

A movable array is interoperable with a C pointer provided
their types correspond. It may be a component of a type that
corresponds to a C struct type with a C pointer of a
corresponding type in the corresponding position. Entities of
such types may be passed in a procedure call under the
existing rules.

If a movable array appears directly in an argument list, the
VALUE attribute refers to the descriptor (usually just an integer
holding the address). If the VALUE attribute is present, the
corresponding actual argument must be a C pointer whose
referenced type is interoperable with the type of the movable
array. If absent, the corresponding actual argument must be a
pointer to a pointer whose referenced type is interoperable
with the type of the movable array. For example,

   void AllocateIntegerArray(int ** a, const int n)
   { *a=(int *) malloc(n*sizeof(int)); }

is interoperable with:

  interface
    subroutine AllocateIntegerArray(a, n), bind(C)
        use iso_c_binding
        integer(c_int), dimension(*), movable :: a
        integer(c_int), intent(in), value :: n
    end subroutine AllocateIntegerArray
  end interface

Note that a movable array provides a way to dereference some C
pointers (cf NOTE 15.7).

