(j3.2006) (SC22WG5.3792) Response on the TR29113 draft N1761

Aleksandar Donev donev1
Tue Dec 9 12:43:55 EST 2008


Hi,

Thanks to train travel downtime, I was able to go through Reinhold's 
missive. Some comments below.

Reinhold Bader wrote:
> Issue 5 - RANK intrinsic:
> ~~~~~~~~~~~~~~~~~~~~~~~~~~
> Is this really needed considering we already have SIZE(SHAPE(X))?
Is AINT really necessary since you can write it so easily? I see no 
reason not to add RANK just because it can be awkwardly handled already.

> Issue 6 - referencing or defining assumed rank entities:
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> It might also be feasible to allow a pointer of rank 1
> to point at such an object:
No, this is not technically possible. Assumed-rank dummies can be 
non-contiguous. So a rank-1 pointer cannot describe their memory layout. 
For the same reason, we only allow rank remapping when the target is 
contiguous.

> Issue 7 - non-interoperable types:
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
> So, if the type definition from example 1 above were replaced by
> 
>   type :: foo
>     integer(c_int) :: i
>     real(c_float), allocatable :: r(:)
>     character(c_int) :: c
>   end type
> 
> the unpacking process in C would need to use a type definition
> 
> typedef struct {
>   int i;
>   void *fdesc;
>   char c;
> } Foo;
No! The component of the type is the descriptor itself, not a pointer to 
the descriptor. And the programmer is not actually given a way to 
declare and directly manipulate Fortran descriptors, by design. They 
manipulate a C "descriptor of a descriptor" and the Fortran one is 
hidden. For example, it can even be different for assumed-shape vs. 
pointer vs. allocatable, it can even be different for different ranks 
vs. assumed-rank vs. scalar, etc.

> Issue 8 - C variable argument lists:
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> with the changes introduced in 08-295 it should now also be possible
> to provide support for vararg interfaces by matching to specifics of
> a Fortran generic interface.
But this is not really vararg, i.e., the ability to pass an arbitrary 
collection of arguments at runtime.

> Suggestion 1 (design change interface creation):
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
> the processor is in principle
> capable of disambiguating interfaces using these features from those
> previously available for C interoperation. Hence I do not consider it
> necessary to provide a separate attribute with the BIND statement.
What "separate attribute" are we talking about?

> (A) C calling a Fortran implementation:
> It would be the responsibility of the processor to
> * automatically generate a wrapper which performs any updates covered by
>   CFI_update_fdesc in the present design, unwraps the entity CFI_desc_t
>   and hands on the Fortran descriptor field to the Fortran-local procedure
>   call.
Sounds nice (for the user). If you can convince the vendors it is a good 
idea :-)

> A direct call from Fortran to the global C name is non-conforming
>   since no type matching CFI_desc_t is available within Fortran; the 
> processor
>   should prevent an interface attempting this from being created.
I don't see how or why the processor should prevent this. It is already 
illegal if the type of the descriptor argument does not match. If there 
is indeed a Fortran equivalent of CFI_desc_t by whatever means, than 
what's wrong with calling the wrapper instead of the direct procedure?

> It is further suggested to provide a constructor (and associated 
> destructor)
> function for the descriptor itself which has as its arguments those 
> entities
> the programmer is responsible for. 
Originally we did have that but we decided against it because the 
argument lists were getting long and some of them had to be ignored (say 
for allocatables the strides did not make sense), so it seemed nicer and 
easier and more efficient to simply let the user directly set the fields 
in the descriptor. Perhaps both methods can be provided for instead of 
just one?

> In contrast to statically determined Fortran code the constructor sets the
> attribute, type and rank of an object at run time.
> Do we oblige the processor to update this information if inconsistent 
> with the defined Fortran interface?
It is illegal to pass a descriptor of the wrong type/rank. The processor 
may insert some check (say in debug mode) and issue an informative 
message, but it is certainly not obliged to "correct" (impossible!) the 
wrong fields.

> (B) Fortran calling a C implementation:
> The wrapper generated from the interface
Where is this wrapper intended to be generated--in the scoping unit 
where the BIND(C) interface appears? What if it is an interface for a 
BIND(C) procedure that is actually written in Fortran. With your design, 
if I understand, Fortran calling that Fortran procedure would call one 
wrapper to generate C descriptors, then the actual procedure will be 
called, and then another wrapper will be called to convert back to 
Fortran. Seems to me like a BIND(C,LANG="C") would be a good idea.

> A C program calling the C interface (untypical) would need to perform
> the construction and allocation, deallocation and destruction of 
> descriptors
> manually before and after the call, respectively.
How? I thought you wanted to remove those API calls?

> Note that this also illustrates that OPTIONAL arguments can also be 
> handled by the wrapping process 
What does the C function pass to the wrapper for arguments not present?

> Suggestion 2 (add assumed-rank-and-size):
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> in analogy to assumed rank (DIMENSION(::)), which one might also call
> assumed-rank-and-shape, a dummy variable can be declared with
> type(foo), DIMENSION(**) :: dummy
I don't quite see the point in this. We already have DIMENSION(*). If 
the only thing we gain is the ability to pass a scalar actual, why can't 
we focus on this instead of adding an exponential dimension statement? 
Probably the reason that is not allowed with DIMENSION(*) is because in 
the old days they would pass an array element as the actual to pass a 
section. But I don't see an actual problem with passing a single scalar 
or even an array element by itself. Perhaps some of the old timers can 
explain?

Best,
Aleks



More information about the J3 mailing list