Allocatable functions and deferred shape

Allocatable functions and deferred shape

I have a function with an allocatable return value, an by mistake I used it in an assignment statement of an explicit shape array. It took me some time figure out what had gone wrong, as the explicit shape array had dimensions that did't depart too much from the array returned by the function and the result was therefore just a rearrangement of the values. As the interface of allocatable functions must be explicit I guess that it is possible for the compiler to pick up that the allocatable function result is assigned to a "static" array, and at least give a warning about unsafe use..?

I don't know if this behavior is permitted by the standard or not, can anyone elaborate on that?

Also, when the array being assigned by the allocatable function actually is ALLOCATABLE, the array descriptor is passed along with the reference(?) to the data, and so the bounds will be correct (even if the lower bound(s) is(are) not 1). Is there any way to get the same behavior for non-deferred-shape-arrays? This question would also pertain to dummy arguments, ie. possible to have deferred-shape instead of assumed-shape for non-allocatable and non-pointer arguments without passing the (lower) bounds explicitly?

8 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.
Steve Lionel (Intel)'s picture

A shape mismatch when the left side of the assignment is not the name of an allocatable array is not allowed by the standard. Unfortunately, Intel Fortran does not currently have the ability to detect this.

When the left side is an allocatable array, and you have enabled the automatic reallocation feature by using /assume:realloc_lhs or /standard-semantics, then the left side is automatically reallocated to match the right side. There is nothing that can be done if the left side is not an allocatable array.

Steve

Thank you for clearing that up, Steve
I use the standard-semantics so everything works fine as long as the lhs is allocatable:)

Could you (or someone else) please comment on the second part of my post? (Possibility to have "deferred-shape behavior" for assumes-shape dummy arrays with Intel Fortran?)

Steve Lionel (Intel)'s picture

I thought I did answer that. No, there is no way to change the shape of a non-allocatable deferred-shape array. Note that the allocatable case involves deallocating the original array and allocating a new one to the correct shape. You could use the RESHAPE intrinsic function to rearrange the right-side expression to match what is on the left side.

Steve

Ok, now I see, you misinterpreted my question :)

I'll try restating it more concisely:
Is it possible to get the "correct" lower bounds of the dummy array that is not allocatable, nor has the pointer attribute?
Ie. that the result of LBOUND is the same for the dummy array as for the actual array

Steve Lionel (Intel)'s picture

You're right - I did misinterpret.

Generally, the answer is "no", and you are by far not the first to be puzzled by this. The official wording in the standard that covers this case is in the description of assumed-shape arrays, 5.3.8.3, where it says:

6 3 The extent of a dimension of an assumed-shape array dummy argument is the extent of the corresponding
7 dimension of its effective argument. If the lower bound value is d and the extent of the corresponding dimension
8 of its effective argument is s, then the value of the upper bound is s + d − 1. If lower-bound appears it specifies
9 the lower bound; otherwise the lower bound is 1.

The reason for this is that the actual argument might be an array expression - an "element sequence". Consider the following:


real a(4:100)

call sub (a(5:80:3))

contains

subroutine sub (b)

real b(:)

What are the bounds of b? What if the dummy argument was something like a([5,2,47])? To avoid such messiness, the standard says that the lower bound of a deferred-shape array, if you didn't give one in the declaration of the dummy, is 1, and the upper bound is derived from the extent (number of elements) of the associated actual. There isn't a way of passing the actual bound information this way. You can do it if you pass a pointer (to another pointer.)

Steve

Ahh...
It's all of those small, but significant, things that I would appreciate if someone gave a note on in the books on Fortran.
Not that it matter in practice, since the Fortran committee has thaught about it for us, but, as you say, I'm not the first one to be puzzled (and somewhat annoyed) by this behavior. Do you know if the F08 contiguous will do anything about this issue?

Steve Lionel (Intel)'s picture

I quoted from the F08 standard, so, no. Contiguity isn't really the issue here - it's coming up with a consistent interpretation across all kinds of actual arguments. It is simplest for the subroutine to assume the lower bound is 1 and the upper bound is the extent, which works with all manner of actual arguments. Again, if the bounds matter, then pass a pointer to a pointer.

Steve

Login to leave a comment.