- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Inside the subroutine, the array is declared as Type(PointerArray), Dimension(*) :: pArray
What I would like to know is how to determine the upper bound of this array from within the subroutine itself (ubound didn't work, I think because the array is allocated at run-time).
The elements contained in the pArray are pointers to derived types.
What I am trying to do is iterate through the elements of the pArray.
If I iterate using some limit, I would need to test to see whether each pointer in the array is associated.
I know in my testing that the array has 5 elements. I need to exit before the 6th is accessed, and this didn't seem to work: If (.not.(Associated(pArray(i)%pCase))) Exit
Note the pCase is a pointer to a derived type.
If I knew the ubound of the array, I could just iterate using that value.
Anyone have any ideas?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Note that Fortran does not have the concept of "array of pointers". Using an array of derived type with pointer components, as you are in the subroutine, is the Fortran way of doing this.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In this case, I have the allocation done in a subroutine two levels up the call stack.
Maybe I'm not quite understanding what you mean by "an explicit interface visible to the caller".
Also, I don't understand why the If (.not.(Associated(pArray(i)%pCase))) Exit didn't work (this is during a Do...Loop). The derived-type pointer pCase was fine for the first 5 elements, and the associated function returned true as expected, but on the sixth element (the array had only 5 elements) I was thinking that the "associated" would return false and I could just exit the iteration. (This was my second option to try to iterate through the pArray... The first was just to use UBOUND).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ASSOCIATED is not going to help you here as you are referencing uninitialized data.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Your array of 5 pointers, was just that: 5 pointers.
The memory following those 5 pointers is undefined, most likely junk, and most likely not NULL.
It is your responsibility to assure that the number of elements of the array can be known (if this is important for your program).
>>Maybe I'm not quite understanding what you mean by "an explicit interface visible to the caller".
subroutine caller
interface
subroutine callee(A)
real :: A(:)
end subroutine callee
end interface
real :: B(1234)
...
call callee(B)
end subroutine caller
---- may have file break here ---
subroutine callee(C)
real :: C(:)
...
end subroutine callee
When compiling caller, the compiler has an interface declaration for callee, and can observe that callee is requesting arguments that is REAL, and is a rank 1 array, and is requesting that the bounds of the array be passed with the call (or reference back to original array descriptor).
Without the interface, the compiler does not know if to pass an array descriptor or pass the address of the first element of the array.
Apparently your choice ofcoding resulted in the address of the first element of the array to be passed to an unbounded array.
It is generally recommended to place your interfaces into a module and then USE the interface module.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I was able to get the code working two ways, and I'd like to know which one is considered to be "better".
1. Subroutine caller contains an internal interface block at the top with only a declaration of the arguments:
Subroutinecaller (App)
Interface
Subroutine H_ECHO (App, ActiveCases)
Include 'H.fi'
Type (HApplication) :: App
Type(PointerArray) :: ActiveCases(:)
End Subroutine H_ECHO
End Interface
Type(PointerArray), Dimension(:), Allocatable :: Cases
...
Call H_ECHO (App, Cases)
...
Return
End Subroutine caller
The second method was to encapsulate the entire subroutine H_ECHO (the "callee") in a module, complete with all of the executable code. In this case instead ofputting a specific interfaceblock(see above) into subroutine caller, I put a "Use H_ECHO1" statement into the caller. So in one example an interface block is used, and in another no interface block is used, but instead "Use" and "Contains" statements are used.
The "callee" (for the second method) looks like:
Module H_ECHO1
Contains
Subroutine H_ECHO (App, ActiveCases)
Implicit None
Include 'H.fi'
Type (HApplication), Target :: App
Type(PointerArray), Dimension(:) :: ActiveCases
...
Return
End Subroutine H_ECHO
End Module H_ECHO1
Which one of these techniques is considered "better" (if any) and why?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
------
Wendy
Attaching or including files in a post
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

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