[comp.lang.fortran] ALLOCATABLE, ARRAY :: A

walton@tybalt.caltech.edu.UUCP (07/07/87)

I've been living with the Fortran-8x standard (July 87 draft) and have
an implementation question: How is one going to do ALLOCATABLE arrays?
It looks very difficult to me, because you are allowed to pass an
allocated ALLOCATABLE array to a subprogram in which the corresponding
dummy argument is *not* ALLOCATABLE.  You can also pass an ALLOCATABLE
array to a subprogram where the dummy argument is ALLOCATABLE, and
said subprogram can allocate and/or deallocate it, as appropriate,
with the change in allocated status affecting the calling program.
   Has anyone seen a Fortran-8x implementation?  How is this done?
(Actually, if anyone knows of a Fortran-8x compiler, I'd love to get a
copy.) 

    Steve Walton, guest as walton@tybalt.caltech.edu
    AMETEK Computer Research Division, ametek!walton@csvax.caltech.edu
"Long signatures are definitely frowned upon"--USENET posting rules

rchrd@well.UUCP (Richard Friedman) (07/08/87)

In article <3164@cit-vax.Caltech.Edu> walton@tybalt.caltech.edu.UUCP (Steve Walton) writes:
>
>(Actually, if anyone knows of a Fortran-8x compiler, I'd love to get a
>copy.) 
>

Many of the compilers on supercomputers are now compiling a 
subset of 8x.  The compiler on the ALLIANT FX/8 now accepts
many of the array syntax constructs in 8x.  More and more
of these things are turning up.  One wishes the standard
would get finalized so that we dont wind up with a mess of
half-standard compilers.
  
About the issue of ALLOCATE arrays, I suspect that nothing
will be done to catch use of an ALLOCATE array as an
argument to a subprogram.  I dont see how the compiler can
detect it unless it is a global compiler.  It just wont work.
Its very hard to implement dynamic arrays in FORTRAN.


-- 
...Richard Friedman [rchrd]                         
uucp:  {ucbvax,lll-lcc,ptsfa,hplabs}!well!rchrd
- or -   rchrd@well.uucp

walton@tybalt.caltech.edu.UUCP (07/09/87)

In article <3515@well.UUCP> rchrd@well.UUCP (Richard Friedman) writes:
>  
>About the issue of ALLOCATE arrays, I suspect that nothing
>will be done to catch use of an ALLOCATE array as an
>argument to a subprogram.  I dont see how the compiler can
>detect it unless it is a global compiler.  It just wont work.
>Its very hard to implement dynamic arrays in FORTRAN.

Yes, I know.  Let me see if I can illustrate the point with
side-by-side FORTRAN and C code.

Normal F77

	real array(10)			float array[10];
	call sub(array)			sub(array);
	     ...			    ...
	subroutine sub(a)		sub(a)
	real a(*)			    float *array;

Fortran-8x, allocated

	real, allocatable:: array(:)	float *array;
	allocate(array(10))		array = malloc(10*sizeof(float));
	call sub(array)			sub(array);
	      [sub is the same as above in both instances]

So far, so good.  What if you want to allocate in the subroutine?

	real, allocatable:: array(:)	float *array;
	call sub(array)			sub(&array);
	      ...			   ...
	subroutine sub(a)		sub(a)
	real, allocatable:: a(:)	    float **a; {
	allocate(a(10))			    *a = malloc(10 * sizeof(int));

Notice that in the C example, we have to pass a pointer to a pointer
to accomplish the within-the-subroutine allocation.  But, the choice
has to be made at compile time, while the Fortran-8x spec seems to
require the choice to be made at run time.  And, if we simply say,
"ALL Fortran-8x arrays will be passed by double-offset (pointer to
pointer)" we break the second example where sub is presumably
expecting a pointer.
      I think the way out is actually in the spec: if you do CALL
SUB(A) you are passing a pointer to a pointer to A.  If you do CALL
SUB(A(5)), you are passing element 5 of a as a scalar, and that is a
call by reference.  To send elements 5 through 10 of A to SUB, you
must do CALL SUB(A(5:10)), in my current reading of the spec.  So, you
can unambiguously tell at compile time whether a scalar or an array is
intended and pass a pointer in the first instance and a
pointer-to-a-pointer in the second instance. 
     Does this sound reasonable?

    Steve Walton, guest as walton@tybalt.caltech.edu
    AMETEK Computer Research Division, ametek!walton@csvax.caltech.edu
"Long signatures are definitely frowned upon"--USENET posting rules

nelson@ohlone.UUCP (Bron Nelson) (07/09/87)

In article <3174@cit-vax.Caltech.Edu>, walton@tybalt.caltech.edu (Steve Walton) writes:
>       I think the way out is actually in the spec: if you do CALL
> SUB(A) you are passing a pointer to a pointer to A.  If you do CALL
> SUB(A(5)), you are passing element 5 of a as a scalar, and that is a
> call by reference.  To send elements 5 through 10 of A to SUB, you
> must do CALL SUB(A(5:10)), in my current reading of the spec.  So, you
> can unambiguously tell at compile time whether a scalar or an array is
> intended and pass a pointer in the first instance and a
> pointer-to-a-pointer in the second instance. 
>      Does this sound reasonable?
> 
Sure it sounds reasonable, and would that it were so, but ...

Section B.3.1.2 of the Apr87 draft clearly states that the old Fortran77
practice of passing an array section by passing the first element must
continue to be supported (the document does go so far as to admit it
is bad form at least).  Thus

	call foo(a(5))
	...
	subroutine foo(s)
	integer s(5)

is still legal.  Of course, foo(a(5:10)) is ALSO legal.

-----------------------
Bron Nelson     {ihnp4, lll-lcc}!ohlone!nelson
Not the opinions of Cray Research

bob@uhccux.UUCP (Bob Cunningham) (07/10/87)

In article <3164@cit-vax.Caltech.Edu> walton@tybalt.caltech.edu.UUCP (Steve Walton) writes:
>
>   Has anyone seen a Fortran-8x implementation?  How is this done?
>(Actually, if anyone knows of a Fortran-8x compiler, I'd love to get a
>copy.) 

We have Alliant's Fortran-8x, and version 3.0.14 which is the current
version I'm using supports ALLOCATE.  It seems to work as advertised
in the spec, though I haven't any idea how it's actually implemented.
As far as a user is concerned it's just a way to dynamically allocate
arrays.

As an aside, the big win of Fortran-8x appears to me to be the nifty
way that you can use array section specifications and vector/scalar
combinations in regular assignment statments.  Eliminates a lot of
unnecessary little DO loops with otherwise garbage up your code.  The
new intrinsics (such as MATMUL and DOTPRODUCT) are handy, too.  For
example, a simplistic version---omitting pivoting---of an LU
decomposition of a matrix can be coded very simply, something like this
(don't use this code!, I'm typing it in from memory and it probably
contains at least one typo):

subroutine lu(a,n)
dimension a(n,n)
do k=2,n-1
	a(k:n,k)=a(k:n,k)-matmul(a(k:n,1:k-1),a(1:k-1,k))
	a(k,k+1:n)=(a(k,k+1:n)-matmul(a(k,1:k-1),a(1:k-1,k+1:n)))/a(k,k)
	end do
a(n,n)=a(n,n)-dotproduct(a(n,1:n-1),a(1:n-1,n))
return
end

[I've probably forgotten something important, but I think you can
get the flavor...though sometimes I wonder whether it's now possible
to write code in Fortran-8x which is as obscure as some APL programs ;-]

walton@tybalt.caltech.edu (Steve Walton) (07/15/87)

In article <250@ohlone.UUCP> nelson@ohlone.UUCP (Bron Nelson) points
out, in response to a posting by me, that Fortran-8x specifically
states that a standard-conforming Fortran-77 program is also standard
conformihng under under Fortran-8x. This torpedoes my idea that A(5)
is a scalar while A(5:10) is an array and thus one can tell at compile
time which is meant.  (This started with wondering how the ability to
ALLOCATE a dummy argument would be implemented.)  He is correct, and I
realized it myself a little while ago.  Expletive deleted.

A rumor which I heard:  The Fortran-8x spec was reported out of
subcommittee some time ago, but the vote in favor of adoption was 15
to 13.  The 15 was the researchers and the 13 were the manufacturers
who complained the language was un-implementable.  The full ANSI
Standards Committee sent the spec back to the subcommittee for further
consideration.  The Europeans, for their part, seem ready to adopt the
current proposed spec, hence the August meeting in the UK to thrash
out an international standard.  Can anyone confirm this?

    Steve Walton, guest as walton@tybalt.caltech.edu
    AMETEK Computer Research Division, ametek!walton@csvax.caltech.edu
"Long signatures are definitely frowned upon"--USENET posting rules

walton@tybalt.caltech.edu (Steve Walton) (07/15/87)

In article <672@uhccux.UUCP> bob@uhccux.UUCP (Bob Cunningham) writes:
>We have Alliant's Fortran-8x, and version 3.0.14 which is the current
>version I'm using supports ALLOCATE.  It seems to work as advertised
>in the spec, though I haven't any idea how it's actually implemented.

Is it actually working fully?  Can you send an ALLOCATE'd array to a
separately compiled Fortran-77 subroutine in which the corresponding
dummy argument is not ALLOCATABLE?  Can you DEALLOCATE an array within
a subprogram which was ALLOCATE'd by the caller, and vice versa
(provided, of course, that the dummy argument is ALLOCATABLE)?  If you
can, I'd love to see an assembly language dump of the generated code
:-). 

    Steve Walton, guest as walton@tybalt.caltech.edu
    AMETEK Computer Research Division, ametek!walton@csvax.caltech.edu
"Long signatures are definitely frowned upon"--USENET posting rules

nelson@ohlone.UUCP (Bron Nelson) (07/16/87)

In article <3247@cit-vax.Caltech.Edu>, walton@tybalt.caltech.edu (Steve Walton) writes:
>                                Can you send an ALLOCATE'd array to a
> separately compiled Fortran-77 subroutine in which the corresponding
> dummy argument is not ALLOCATABLE?  Can you DEALLOCATE an array within
> a subprogram which was ALLOCATE'd by the caller, and vice versa
> (provided, of course, that the dummy argument is ALLOCATABLE)?

Although this article asks this question specifically about the Alliant
compiler, we both have been having trouble seeing how this can be done
at all by anybody.  After careful reading of the proposed standard, I think
I now understand how this can be done in a sensible way (and of course,
I feel stupid for not noticing it sooner).

The trick is that in order to use any of the fancy features of 8x, the
called procedure MUST have an explicit procedure interface definition.
Thus the calling procedure CAN tell at compile time what the called
procedure expects to recieve.  Thus, foo(a(5:10)) and foo(a(5)) are
NOT both legal; if routine foo expects an array section, all callers of
foo must include foo's interface definition, and so foo(a(5)) will give
an error.  Similar restrictions apply to the use of allocatable arguments
that will be (de)allocated by the called routine.  If the caller lacks
an interface definition for the routine to be called, it can pass arguments
according to the Fortran77 rules.

This example goes a long ways towards pointing out that 8x is not just
an extension of Fortran, it is a new and different language.  The standards
committee has done a good job of making sure the two languages can co-
exist, but they do not really "mix" very smoothly.

Anyway, sorry for the confusion.  Hope this is of use.

-----------------------
Bron Nelson     {ihnp4, lll-lcc}!ohlone!nelson
Not the opinions of Cray Research
I don't know what language I'll be writing a compiler for in '88,
but I know it will be called Fortran.

bob@uhccux.UUCP (Bob Cunningham) (07/19/87)

It turns out the Alliant's implementation is not a full Fortran-8x
version.  Allocatable arrays can only be used under certain (though
very useful) circumstances.  I've forwarded more details, including
some pseudo-assembly-language dumps to Steve.  Looks like it's
still an open question how the full features might be implemented.