# (j3.2006) lower bounds of results of array valued functions

Bill Long longb
Sat Jul 25 17:01:42 EDT 2009

Robert Corbett wrote:
> Consider the following program
>
>        FUNCTION F()
>          POINTER F
>          REAL F(:)
>
>          ALLOCATE(F(3:4))
>        END
>
>        FUNCTION G()
>          REAL G(4:5)
>
>          G = 0.0
>        END
>
>        FUNCTION H()
>          REAL, ALLOCATABLE :: H(:)
>
>          ALLOCATE(H(5:6))
>          H = 0.0
>        END
>
>        PROGRAM TEST
>          REAL A(2:3)
>          ALLOCATABLE B
>          REAL B(:)
>          INTERFACE
>            FUNCTION F()
>              POINTER F
>              REAL F(:)
>            END FUNCTION
>          END INTERFACE
>          INTERFACE
>            FUNCTION G()
>              REAL G(4:5)
>            END FUNCTION
>          END INTERFACE
>          INTERFACE
>            FUNCTION H()
>              REAL, ALLOCATABLE :: H(:)
>            END FUNCTION
>          END INTERFACE
>
>          PRINT *, LBOUND(A)
>          PRINT *, LBOUND((A))
>          PRINT *, LBOUND(F())
>          PRINT *, LBOUND(G())
>          PRINT *, LBOUND(H())
>          B = H()
>          PRINT *, LBOUND(B)
>        END
>
> One vendor's implementation (not Sun's) produces the following output
> for the program
>
>   2
>   1
>   3
>   4
>   5
>   5

The last value (lbound(b)) should be 1. B is automatically allocated on
assignment. In that case, the shape of the expression is used for B, but
the bounds of B are not determined by the expression.  Consider a
different case:

B = x(2:4) + y(8:12:2)

In this example, there is no reasonable way for the expression to
provide a lower bound for B.

>
> Another implementation produces
>
>   2
>   1
>   1
>   1
>   1
>   1
>
> Two other implementations produce
>
>   2
>   1
>   1
>   1
>   1
>
> and an error.

I suspect that these compilers do not have automatic allocation on
assignment implemented yet.

>
> I can see how to interpret the standard to allow either of the first two
> sets of results.  I suspect that most members of the committee would say
> that the second set of results is correct.  Does anyone think the first
> set of results matches the intent of the standard?
>
> I was surprised by the second line of the results.  I thought that a
> parenthesized whole array would still be a whole array.

I tried 5 compilers. Compiler number one agrees with you here:

> ./a.out
2
2
3
4
5
1

But the second compiler does not:

> ./a.out
2
1
3
4
5
1

Nor does the third:

> ./a.out
2
1
3
4
5
661988912

(This compiler does not support the f03 auto-allocation feature, so the
last value is just stack trash).

>
> I am interested in knowing if any other implementations produce results
> that differ from the second set of results.

Of the 5 compilers I tried, the fourth one produced

> ./a.out
2
1
1
1
1
1

The fifth compiler could not handle the source file (at least with
default options), but then they do not claim f03 compliance.

Even though I could find only 1 out of 5 compilers that produced the
lower bounds of 1 in the function result cases, this does seem to
correspond to the literal words in the standard which hinge on "whole
array".  On the other hand, this convention makes it hard to determine
the actual lower bounds that were specified for the function result
value. Since you can't affix subscripts to a function reference, it
would seem that this somewhat contrived example is one of the few places
where it makes any difference. In that isolated case, the apparently

case (plus an interface block in the main program for sub)

call sub (H())

...

subroutine sub (aa)
real,allocatable :: aa(:)
print *, lbound(aa)
end

I would expect the descriptor for the result of H() to be passed to sub,
and 5 printed.  Indeed, the one compiler I tried that outputs the 2 1 1
... result prints 5 in sub, as do the "second" and "third" compilers
above. At least where it actually matters, there seems to be better
agreement.  However, it is a bit odd that lbound(aa) and lbound(H()) get
different results with the fourth (seemingly conforming) compiler. The
second and third compilers get the same results for lbound(H()) and
lbound(aa).  I'm not sure that specifying lbound(H()) to be 1 was
actually intentional, or maybe these examples were not considered.

Cheers,
Bill

>
> Robert Corbett
> _______________________________________________
> J3 mailing list
> J3 at j3-fortran.org
> http://j3-fortran.org/mailman/listinfo/j3

--
Bill Long                                   longb at cray.com
Fortran Technical Support    &              voice: 651-605-9024
Bioinformatics Software Development         fax:   651-605-9142
Cray Inc., 1340 Mendota Heights Rd., Mendota Heights, MN, 55120