From: PGK on
Hi all,

Is it legal or sensible to declare (array) function results as
allocatable? I was curious, as I'm implementing a Fortran compiler,
and I had the idea that functions such as "size" needn't actually
evaluate the expression. Anyway, using "allocatable" for a function
argument implies that a function would actually need to be ran. It
feels like it should be illegal, but I get no warning from my
compilers (see code below). Any thoughts?

module m

public :: zot

contains

function zot(sz) result(a)
integer, intent(in) :: sz
integer, allocatable, dimension(:) :: a

allocate( a(sz) )
a = sz
end function zot

end module m

program main

use m
print *, size(zot(5))

end program main
From: Reinhold Bader on
Hello,

PGK schrieb:
> Hi all,
>
> Is it legal or sensible to declare (array) function results as
> allocatable?

In Fortran 95, it is not allowed. In Fortran 2003 (and, slightly earlier,
via the facilities described in TR15581) it is legal.

Such a facility does make sense e.g. if you do not know the size of
the result array upon invocation of the function. Note that the
function result is deallocated after the expression has been evaluated;
for an assignment you still have the problem that in F95+TR effectively
two invocations of the function are needed to obtain a legal array assignment
in all cases:

res(1:size(zot(sz)) = zot(sz)

and of course res must be large enough to hold the result. In Fortran
2003 this problem is alleviated by auto-(re)allocation:

integer, allocatable :: res(:)
:
res = zot(sz)

Regards
Reinhold

> I was curious, as I'm implementing a Fortran compiler,
> and I had the idea that functions such as "size" needn't actually
> evaluate the expression.
> Anyway, using "allocatable" for a function
> argument implies that a function would actually need to be ran. It
> feels like it should be illegal, but I get no warning from my
> compilers (see code below). Any thoughts?
>
> module m
>
> public :: zot
>
> contains
>
> function zot(sz) result(a)
> integer, intent(in) :: sz
> integer, allocatable, dimension(:) :: a
>
> allocate( a(sz) )
> a = sz
> end function zot
>
> end module m
>
> program main
>
> use m
> print *, size(zot(5))
>
> end program main
From: Arjen Markus on
On 25 nov, 15:08, Reinhold Bader <Ba...(a)lrz.de> wrote:
> Hello,
>
> PGK schrieb:
>
> > Hi all,
>
> > Is it legal or sensible to declare (array) function results as
> > allocatable?
>
> In Fortran 95, it is not allowed. In Fortran 2003 (and, slightly earlier,
> via the facilities described in TR15581) it is legal.
>
> Such a facility does make sense e.g. if you do not know the size of
> the result array upon invocation of the function. Note that the
> function result is deallocated after the expression has been evaluated;
> for an assignment you still have the problem that in F95+TR effectively
> two invocations of the function are needed to obtain a legal array assignment
> in all cases:
>

That can be alleviated by passing the result to another routine:

real, allocatable, dimension(:) :: res
call store_data( res, zot(zs) )

subroutine store_data( res, zot )
real, allocatable, dimension(:) :: res
real, dimension(:) :: zot

allocate( res(size(zot) )
res = zot
end subroutine

Regards,

Arjen
From: Richard Maine on
PGK <graham.keir(a)gmail.com> wrote:

> Is it legal or sensible to declare (array) function results as
> allocatable?

Yes. As Reinhold notes, this was introduced to the language with f95
TR15581 (which I usually just refer to as the allocatable stuff TR so
that I don't have to look up the number), and became part of the base
language with f2003. Most current f95 compilers support the TR.

> I was curious, as I'm implementing a Fortran compiler,
> and I had the idea that functions such as "size" needn't actually
> evaluate the expression.

You'll need a *(LOT* better understanding of things like that in order
to get a compiler particularly close to working. There is no such
general provision. There are cases where SIZE does not need to evaluate
its arguments, but it is quite trivial to write cases where the
arguments essentially must be evaluated. You don't need allocatable
arrays at all, much less as function results, for that to happen. For
example, consider

size(x(1:f(n))

where f is some integer function.

See the standard's definition of initialization expressions for cases
where it is guaranteed that you don't need to evaluate any user
functions. (The standard doesn't say that in so many words, but it is
part of the idea behind initialization expressions - that they can be
evaluated at compile time). Some cases of intrinsic functions such as
SIZE can be used in initialization expressions, but there are
limitations on the arguments.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
From: PGK on
Thanks everyone.

That's a very helpful example Richard. I'd certainly need to
evaluate f(n), but thanks to the initialization expressions
you mention, I wouldn't need to evaluate g:

size(g(x(1:f(n))))

Well, at least pre-TR15581...

Regards,
Graham