Reputation: 1209
I have a function which returns an array:
PURE FUNCTION set_Xgrid() RESULT(x_grid)
REAL(dp), DIMENSION(:), ALLOCATABLE :: x_grid
INTEGER :: ii
ALLOCATE(x_grid(0:Nx-1))
DO ii=0,Nx-1
x_grid(ii) = x_o + ii*dx
END DO
END FUNCTION
I then just call this function like this:
REAL(dp), DIMENSION(:), ALLOCATABLE :: x
ALLOCATE(x(0:Nx-1))
x = set_Xgrid()
DO ii=0,Nx-1
PRINT '(I4,A10,F10.7)', ii, ", x(ii) = ", x(ii)
END DO
Output (first few lines):
0, x(ii) = 0.0000000
1, x(ii) = 0.0101010
2, x(ii) = 0.0202020
Even though the above code works as expected, I do not really understand how it works.
I thought the RESULT
of a function was an implicit INTENT(OUT)
and worked the same way: any value prior to the call of the function was ignored and the variable was automatically deallocated. If that is the case, the code somehow remembers that the variable x
was initialized starting at index 0.
Is this the right way to have the returned array of a function start at index 0? Also, I'd like to understand what happens when a function returns an array.
Upvotes: 2
Views: 133
Reputation: 32451
Vladimir F's answer covers much of what you need to know. There is more detail to add, however.
It is important to repeat, first, that a function result is not at all like an intent(out)
dummy variable. Except in cases that don't apply here the function result acts as an expression rather than a variable.
You ask
If that is the case, the code somehow remembers that the variable x was initialized starting at index 0.
This is a consequence of the rules of intrinsic assignment (see, for example, 7.2.1.3 of Fortran 2008). If the variable on the left of the assignment is an allocatable variable it may be deallocated first. This "may" is important: it isn't always deallocated.
If the variable array is deallocated then it will be reallocated with the bounds/shape of the expression on the right. The lower bound of the expression will be 1
regardless of the bounds of the function result.
However, in your case the shape of the variable array is the same as the shape of the expression. Here, the variable is not deallocated before it is reallocated. It thus keeps its original bounds (lower bound 0
).
Upvotes: 1
Reputation: 60088
There is not much point returning an array starting at a specific index. It is not important anyway:
x(3:5)
x = f()
will work for any function returning the array of the right size 3, even if it starts from 42 inside the function.
It definitely does not work as intent(out), allocatable
argument. The values are just assigned to the right place of the array, counting from the array start, not using the actual indexes.
If the variable is not allocated at all prior the assignment
real, allocatable :: x(:)
x = f()
then it is allocated to start at 1 with the right size, again, where the result started inside the function does not matter.
Upvotes: 2