- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have a question about the index numbering of arrays in Fortran. Consider this small code example:
module IndexModule
contains
subroutine Asub(A)
integer, allocatable :: A(:)
allocate(A(3))
A(1) = 1 ; A(2) = 2 ; A(3) = 3
end subroutine Asub
end module IndexModule
program IndexTest
use IndexModule
implicit none
integer, allocatable :: A(:)
call Asub(A)
!write(*,*) A(1), A(2), A(3)
write(*,*) A(0), A(1), A(2)
end program IndexTest
When I compile and run the program as it is shown it runs fine. But if I uncomment the commented write line I get and array bounds exceeded error. A closer incpection in the debugger reveals what is wrong. When A is allocated in the subroutine it has indices 1, 2, 3, as expected. But when it is returned to the mail program it has indices 0, 1, 2. Why is that? It should be mentioned that I use CVF 6.6 (with Windows XP) but plan to migrate to IVF in the near future. This behaviour has caused some nuicances in my programs, as I then have to check the lower bounds of my subroutine-generated arrays using lbound. Am I doing anything wrong?
Best regards, j_clausen
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Well, the Compaq Fortran had a bug in its implementation, so it does not quite make sense to consider it within the framework on the Standard.
The question "does the standard say anything about the indexing conventions" is too broad to be succinctly answered. The standard says quite a bit about "indexing conventions", because they have to be uniform across platforms, so that you can produce portable programs.
With my mind-reading hat on, I presume that you need the information about what happens when an array is passed to a routine. The short answer is that POINTER and ALLOCATABLE array preserve their bounds across routine boundaries, but assumed-shape dummies get remapped to lower bound of 1:
[fortran]integer, target:: I(2:5) integer, pointer:: P(:) integer, allocatable:: A(:) P=>I call Test(I, P, A) write(*,*) "I: ", lbound(I), ubound(I) !2,5 write(*,*) "P: ", lbound(P), ubound(P) !2,5 write(*,*) "A: ", lbound(A), ubound(A) !2,5 contains subroutine Test(I, P, A) integer, target:: I(:) integer, pointer:: P(:) integer, allocatable:: A(:) write(*,*) "I: ", lbound(I), ubound(I) !1,4 write(*,*) "P: ", lbound(P), ubound(P) !2,5 allocate(A(2:5)) write(*,*) "A: ", lbound(A), ubound(A) !2,5 end subroutine Test end program [/fortran]
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
David
- 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
That's what I like to hear, i.e. that this is not a general Fortran issue. This will make the code in IVF much prettier than that of CVF.
j_clausen
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have now migrated to Intel Visual Fortran and the problem in my initial post has vanished, as mentioned by David. This leads me to a question: Does the standard say anything about the indexing conventions? I.e. does Compaq Fortran comply with the Fortran 95 standard, even though the code sample shown initiallydon't work?
j_clausen
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Well, the Compaq Fortran had a bug in its implementation, so it does not quite make sense to consider it within the framework on the Standard.
The question "does the standard say anything about the indexing conventions" is too broad to be succinctly answered. The standard says quite a bit about "indexing conventions", because they have to be uniform across platforms, so that you can produce portable programs.
With my mind-reading hat on, I presume that you need the information about what happens when an array is passed to a routine. The short answer is that POINTER and ALLOCATABLE array preserve their bounds across routine boundaries, but assumed-shape dummies get remapped to lower bound of 1:
[fortran]integer, target:: I(2:5) integer, pointer:: P(:) integer, allocatable:: A(:) P=>I call Test(I, P, A) write(*,*) "I: ", lbound(I), ubound(I) !2,5 write(*,*) "P: ", lbound(P), ubound(P) !2,5 write(*,*) "A: ", lbound(A), ubound(A) !2,5 contains subroutine Test(I, P, A) integer, target:: I(:) integer, pointer:: P(:) integer, allocatable:: A(:) write(*,*) "I: ", lbound(I), ubound(I) !1,4 write(*,*) "P: ", lbound(P), ubound(P) !2,5 allocate(A(2:5)) write(*,*) "A: ", lbound(A), ubound(A) !2,5 end subroutine Test end program [/fortran]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you very much Jugoslav. Your mind-reading hat works perfectly.
j_clausen

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