(j3.2006) (SC22WG5.4649) [ukfortran] AW: Vote on N1904

Malcolm Cohen malcolm
Wed Mar 14 21:03:46 EDT 2012

Nick Maclaren wrote:
>It was that MPI receive buffers are a well-known example of where
>output-only assumed-type arguments are needed.  While there is no
>difficulty in using INTENT(INOUT) or no INTENT, having to specify
>something other than what you intend is poor software engineering.

I agree, but we intend TYPE(*) to be poorly engineered in any case (see much 
lower down re void*).

>There is no reasonable sense in which assumed-type is incompatible
>with INTENT(OUT) as such.  The only incompatibility is with some of
>the semantic requirements that have been attached to INTENT(OUT) for
>some types.

Some might disagree that INTENT(OUT) and (INOUT) are such simple concepts.

INTENT(OUT) necessarily involves properly disposing of the previous contents, 
and so deallocation and finalisation, and also initialisation to the default 
state.  For "traditional" types, that means become undefined (potentially "trap 
representations" to use C-speak), but we have had non-traditional types since 
1997 [F95] and 1998 [alloc TR]).

One cannot do either of these things if you don't have the necessary information 
(type and shape).  Traditionally, DIMENSION(*) was missing the shape part of 
that information and so INTENT(OUT) DIMENSION(*) has some restrictions.

ASIDE: In hindsight one might unreasonably contend that assumed-size was 
implemented wrongly by the people who just passed the base address and not also 
the number of elements (or "designed wrongly" given that that was the intent of 
the design) but that is water under the bridge.

I would not want C routines to have to perform the 
deallocation/finalisation/initialisation dance for TYPE(*) INTENT(OUT), because 
(a) we have not [yet] provided them with a mechanism to do that, (b) even if we 
did, they would forget to do it most of the time, and (c) most of the rest of 
the time they would get it wrong.

Anyway, DIMENSION(*) already has the restrictions it needs to handle TYPE(*) - 
viz INTENT(OUT) is not allowed.

The obvious simple "big hammer" that seems to work is similar, to disallow 
TYPE(*) INTENT(OUT) everywhere.

In fact, because we want to pass TYPE(*) except for alloc/ptr/ass-shape/ass-rank 
to a BIND(C) routine as a plain address [because it's much too much work for the 
user to type "C_LOC(...)"!], and this will necessarily exclude the type info, it 
appears to be the only restriction that will actually work at all.

I see no reasonable way of improving the INTENT of TYPE(*) that would preserve 
our "intent" that it be implementable with "void*".  Various unreasonable ways 
exist (non-constraint restrictions that are not only undetectable at compile 
time but also undetectable at runtime without heroic efforts and sometimes not 
even then), but they do not seem worth pursuing.

Bill Long wrote:
>I agree it is overkill, but for such a narrowly focused feature as TYPE(*), I 
>think that is an acceptable trade-off.

Contrariwise, I think the big hammer is the smallest reasonable change that is 
consistent with our "void *" intent.  If we ever want to ease the restriction, 
we probably need to drop the "void *" idea...

If we dropped the void* idea and made TYPE(*) passed by some kind of descriptor 
(e.g. C descriptor) all the time instead, much smaller reasonable fixes are 
available.  For example, disallowing INTENT(OUT) TYPE(*) arguments for BIND(C) 
routines would be sufficient, or even just requiring BIND(C) routines with 
INTENT(OUT) TYPE(*) to be written in Fortran would also be sufficient (though a 
slightly strange requirement).

................................Malcolm Cohen, Nihon NAG, Tokyo. 

More information about the J3 mailing list