- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

I have a function that initializes a 0-bound array of a custom type. This is for a simulation, and the function returns an array of results, with the first item (0 index) being the initial conditions.

function model3_run(this, end_time, steps) result(sol) class(model3), intent(inout) :: this real(8), intent(in) :: end_time integer, intent(in) :: steps type(state3), allocatable :: sol(:) real(8) :: time_step integer :: i allocate(sol(0:steps)) ! allocate the 0-bound array sol(0) = this%initial_state time_step = end_time / steps do i=1,steps sol(i) = this%step(sol(i-1), time_step) end do end function

when I use `lbound(sol)` and `ubound(sol)` here I get the expected results.

Now the main program runs this code, and stores the results in an allocatable array.

type(model3) :: sim type(state3), allocatable :: solution(:) solution = sim%run(0.1d0, 10)

The problem is that `solution` is no longer a 0-bound array. The first element is stored in index=1.

So my question is as follows: if I am doing it wrong, **what is the correct way to allocate a 0-bound dynamic array in a function an use it outside from the main program**?

[Intel Parallel Fortran XE 2018 update 5, Windows 7 64-bit, Visual Studio 2017 15.9.14]

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

That is the correct behavior, as the function return is just a value. The only way to maintain bounds in the case of a function return is to return a pointer and use pointer assignment in the main program. Rather than use a function you could make it a subroutine and pass the allocatable array as an intent(out) argument.

Link Copied

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

That is the correct behavior, as the function return is just a value. The only way to maintain bounds in the case of a function return is to return a pointer and use pointer assignment in the main program. Rather than use a function you could make it a subroutine and pass the allocatable array as an intent(out) argument.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Steve Lionel (Ret.) (Blackbelt) wrote:That is the correct behavior, as the function return is just a value. The only way to maintain bounds in the case of a function return is to return a pointer and use pointer assignment in the main program. Rather than use a function you could make it a subroutine and pass the allocatable array as an intent(out) argument.

I understand. I like the `solution = sim%run(0.1d0, 10)` semantics, but for Fortran that is a copy operation and the copy does not preserve bounds. I hope I understand correctly that for Fortran `B=A` means make a copy of `A` into `B`.

What if I allocate my array as 0-bound before the function return, will in then produce the result I expect?

allocate(solution(0:n)) solution = sim%run(0.d0, 10)

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

JAlexiou wrote:..

What if I allocate my array as 0-bound before the function return, will in then produce the result I expect? ..

You may want to be careful: if the expression (e.g., the result of sim%run(0.0d0, 10)) can end up with a different shape than used in your ALLOCATE statement and your compiler conforms to current standard, the assignment (solution = .. ) - assuming it's intrinsic - can lead to deallocation of the variable and reallocation with the shape of the expression. Under this circumstance, the lower bound of LHS will become 1.

If the use of a lower bound other than 1 is important to you and you have scenarios where the function result can have different shapes, you may want to look into **defined assignment** and evaluate this option toward your coding needs involving variables with the ALLOCATABLE attribute.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

JAlexiou wrote:

What if I allocate my array as 0-bound before the function return, will in then produce the result I expect?

allocate(solution(0:n)) solution = sim%run(0.d0, 10)

Yes, that should work., but it's still a copy, which you said you were concerned about. Because the variable and the result have the same shape (number of elements in each dimension), the variable doesn't get reallocated.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page