- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- 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
- 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
- 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
- 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
- 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
- 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