From owner-sc22wg5  Thu Jul 26 18:33:00 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 SAA17867
	for <SC22WG5@dkuug.dk>; Thu, 26 Jul 2001 18:32:59 +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 RAA26098;
	Thu, 26 Jul 2001 17:32:53 +0100
Received: (from jkr@localhost)
	by jkr.cc.rl.ac.uk (8.8.8+Sun/8.8.8) id RAA19983;
	Thu, 26 Jul 2001 17:35:05 +0100 (BST)
Date: Thu, 26 Jul 2001 17:35:05 +0100 (BST)
From: John Reid <jkr@rl.ac.uk>
Message-Id: <200107261635.RAA19983@jkr.cc.rl.ac.uk>
To: SC22WG5@dkuug.dk
Subject: Another look at dynamic arrays and interfacing with C
Cc: donev@pa.msu.edu
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"

                                            ISO/IEC JTC1/SC22/WG5-N1442

        Another look at dynamic arrays and interfacing with C

                          John Reid 


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


I wrote N1441 with Aleksandar Donev 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.

I sent a copy to N1441 to the WG5 email list and obtained the response
from Richard Maine that is attached as Annex 1. His view is that

  1. it is already possible, by using the C_LOC intrinsic, for a
     Fortran procedure, while being called from C, to allocate an 
     array and make that array available to the C code, and

  2. it would be possible, by adding another intrinsic that
     constructs a Fortran pointer from a C pointer, for an array that
     is allocated in C to be available to Fortran code.

A possible extra intrinsic was proposed in J3/00-168, which is
attached as Annex 2. 

The way I read the draft standard is that 15.2.5 does not include
allocatable arrays in the set of entities that are interoperable and
C_LOC requires X to be interoperable. On the other hand, in C_LOC I
find 'It shall not be an array pointer, an assumed shape array, or an
array section', which does not exclude an allocatable array. I
would like edits to be made that make it clear that allocatable
arrays are permitted. 

I would also like consideration to be given to adding an extra 
intrinsic on the lines of that proposed in J3/00-168.

I do not want the proposal in N1441 to be considered. 

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


ANNEX 1. Message from Richard Maine.

I won't be at the London meeting, and the J3 meeting before it has
already happened, so email is my only avenue for commenting on this.
(That in itself concerns me - to have what looks like a major new
proposal with this little chance for review before it possibly
becomes a new requirement.)

This seems like an awfully large new requirement/proposal for this
late in the process.  We are now supposed to be in the integration
phase, which is all to short for a good job as is.  I would expect
this to substantially impact integration.

 > 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.

I do not believe that to be the case.  It appears to me that the
Fortran subroutine could use a saved, target, allocatable array,
in conjunction with the C_LOC intrinsic to do such a thing.

I agree the use of allocatable would place some pretty significant
restrictions on the usability of this.  I would think that allowing
C_LOC to take pointer arguments would be a far simpler way of
extending this.  Even if we add some new definitions to restrict
the class of pointers it could reference to those that were
"contiguous", I'd think it a lot less complication to define that
than to introduce a whole new class of pointer, with a new syntax
and lots of new interactions to worry about.

 > 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.

Agree.  And a hugely simpler solution to that was proposed and
rejected.  To my knowledge, the only reason for the rejection was
that it did allow Fortran pointers to point to C allocated things.
I don't think the rejection was based on the specific mechanism so
much as the end result.  If we want to allow this, I propose that
we resurrect that idea, which was very simple and really had no
other complications that I can think of.  (Ok, I'm biased; I liked
the idea before, and I still do.)  That idea was basically to
have an intrinsic that generated a Fortran pointer from an address
and a mold.  See paper J3/00-168.  One could argue spelling trivia,
but the idea seems pretty simple and workable to me.

 > It also has the side benefit of providing a dynamic array within
 > Fortran that has far less storage overheads than allocatable or
 > pointer arrays.

I don't believe that side effect is, in itself, of major enough
impact to justify such a late proposal.

The C/Fortran interop aspects, which I do agree are important,
have, in my opinion, simpler solutions, as described above.  I
would think it more appropriate to pursue those solutions than
this new syntax.  In particular, as long as we allow some way to
dereference C pointers, it is going to be hard (in my opinion)
to explain why we don't have something like the proposal of
paper j3/00-168.  So let's see how much of the problem that
solves by itself.


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

ANNEX 2

                                                          J3/00-168

Date:       2000/05/08
To:         J3
From:       William Mitchell
Subject:    Fortran pointer from C pointer
References: 00-007, 00-121, 00-149, 00-150

Several deficiencies in C interoperability were presented in 00-121.  Many
of these were resolved in 00-149 and 00-150, and some were determined to
be impossible to address, however three important issues were determined to
be "too hard" to address at this time.  These are:

- Provide a means by which a character string of unknown length can be
returned from a C function, both as an argument and as a function
result.

- Provide a means by which an array allocated in a C function can be
returned to a calling Fortran procedure.

- Provide a means by which a C pointer to a function can be returned to
Fortran and assigned to a procedure pointer.

All of these issues can be easily solved by providing a means of
constructing a Fortran pointer from a C pointer.  This paper proposes
that a function be added to the ISO_C_BINDING module to provide this
functionality.  The function takes a C pointer, a mold to determine the
result type, and, if the result is an array, a shape and returns a
Fortran pointer associated with the same target as the C pointer.  The
author is not married to the name CPTR_TO_FPTR.

Edits to 00-007:

[387:46]
  Add:

The CPTR_TO_FPTR function provides a means of defining a Fortran
pointer that is associated with the same target as a C pointer.

CPTR_TO_FPTR(CPTR,MOLD [,SHAPE])

   Description.  Constructs a pointer associated with the same target as
                 CPTR and with the characteristics of MOLD.

   Class.  Transformational function.

   Arguments.

   CPTR         shall be a scalar of type C_PTR

   MOLD         shall be a pointer and may be of any type or may be a
                procedure pointer.  Its pointer association status may be
                undefined, disassociated or associated.  If its status is
                associated, the target need not be defined with a value.

   SHAPE (optional) shall be of type integer, rank one, and constant size.
                It shall be present if and only if MOLD is an array pointer.
                Its size shall be equal to the rank of MOLD.  It shall not
                have an element whose value is negative.

   Result Characteristics.  The result is of the same type and type
                parameters as MOLD.

   Case (i):   If MOLD is a scalar pointer, the result is a scalar pointer.

   Case (ii):  If MOLD is an array pointer, the result is an array pointer
               of shape SHAPE.

   Case (iii): If MOLD is a procedure pointer, the result is a procedure
               pointer with an implicit interface.

   Result Value.  The result is associated with the same target as CPTR.

NOTE 16.x

The following example illustrates how to access a C character string that
was allocated and set by a procedure with the prototype

void getstring(char *string, int *nchar)

by using either a pointer to scalar character string of appropriate length
or an array of characters of length one.

USE ISO_C_BINDING
INTERFACE
   BIND(C,NAME="getstring") SUBROUTINE GETSTRING(STRING,NCHAR)
   USE ISO_C_BINDING
   TYPE(C_PTR) :: STRING ! NOTE it is not VALUE
   INTEGER(C_INT), INTENT(OUT) :: NCHAR
   END SUBROUTINE GETSTRING
END INTERFACE
TYPE(C_PTR) :: C_STRING
INTEGER(C_INT) :: NCHAR
CHARACTER(LEN=:,KIND=C_CHAR), POINTER :: SCALAR_STRING
CHARACTER(LEN=1,KIND=C_CHAR), POINTER, DIMENSION(:) :: ARRAY_STRING
CALL GETSTRING(C_STRING,NCHAR)
ALLOCATE(SCALAR_STRING(NCHAR))
SCALAR_STRING => CPTR_TO_FPTR(C_STRING,SCALAR_STRING)
ALLOCATE(ARRAY_STRING(NCHAR))
ARRAY_STRING => CPTR_TO_FPTR(C_STRING,ARRAY_STRING,(/NCHAR/))

[388:5-6]
  Delete Note 16.7

