- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I currently have a rank one array tb which is equivalenced to a rank four array ta(81,81,3,2).
The subsequent code uses tb exclusively (not ta), and the indexing into tb is variable.
So, I can access ta data using tb(i), where i is any integer from 1 to 81*81*3*2 = 39366 without experiencing any run time out-of-bounds errors.
What I would like to do is remove the equivalencing and somehow change tb to a pointer array, so that I can use the same indexing tb(i) as before.
So I changed tb to a rank 1 pointer array with the statement Real, Pointer :: tb(:)
Then I pointed to the rank 4 array using tb => ta(:,1,1,1)
The end result of this is that with the "Check Array Bounds" option on, the compiler (correctly) flags the over-bounds error at run-time when tb accesses ta with a subscript greater than 81.
However, when I turn the "Check Array Bounds" off, the program works perfectly, and gives me the correct answer.
The problem is, I like the array bounds checking and I would like to keep it on if possible.
My question is: Is there a better way to remove the equivalencing (using pointer arrays, perhaps?) and if so, can someone provide an example?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
USE ISO_C_BINDING
REAL(C_FLOAT), TARGET :: rank_four(na,nb,nc,nd)
TYPE(C_PTR) :: intermediate_c_ptr
REAL(C_FLOAT), POINTER :: rank_one(:)
...
intermediate_c_ptr = C_LOC(rank_four)
CALL C_F_POINTER(intermediate_c_ptr, rank_one, [ SIZE(rank_four) ])
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'll comment that Intel Fortran does now support bounds remapping of pointers, but that won't let you change the rank.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm not too familiar with ISO_C_BINDING.
Would "Use ISO_C_BINDING" be platform compatible (Win-OS and Linux)?
Is there any way to do it without using the "Use" statement?
Can you provide a small example of "bounds remapping of pointers"?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Use ISO_C_BINDING seems to result in:
error #6285: There is no matching specific subroutine for this generic subroutine call. [C_F_POINTER]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
USE , INTRINSIC :: ISO_C_BINDING
which is a different module.
- 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
John, can you show us your test source?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I had made the mistake of putting in a const int for the third argument on the call, which is what caused the error message :
CALL C_F_POINTER(C_LOC(ta), tb, 1) caused the error,
whereas
CALL C_F_POINTER(C_LOC(ta), tb, [SIZE(ta)]) did not.
So, this is one option and turning off the array bounds checking is one option.
Is there any option which could work with array bounds checking on but without using the ISO_C_BINDING?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Why not use ISO_C_BINDING? This is standard Fortran. I can't think offhand of another method that would work that isn't an extension.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
My only reason is platform and compiler compatibility. Although currently we use Intel's Fortran compiler on both Windows and Linux OS, we also have HP compilers on some of our older machines, and I am not entirely sure that some of the compilers we have support Fortran beyond F77. Plus, we sometimes have to work with customers who use gfortran, which I'm not sure of either. So I have been hesitant at times tomodify any of our legacy codes to incorporate the "Use" keyword (exept for the module which deals with compatibility... I can't remember its name offhand). Probably not great reasons, and I would love to hear any argument which would put my concerns more at ease.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
[fortran]! ifort /check:all /warn:all /stand:f03 equiv.f90 PROGRAM equiv IMPLICIT NONE REAL :: rank_four(2,3,4,5) INTEGER :: i !**** rank_four = RESHAPE([(REAL(i), i=1,SIZE(rank_four))], SHAPE(rank_four)) CALL proc(rank_four, PRODUCT(SHAPE(rank_four))) PRINT "(99(4(F8.1,:),/))", rank_four CONTAINS SUBROUTINE proc(rank_one, N) INTEGER, INTENT(IN) :: N REAL, INTENT(INOUT) :: rank_one(N) !**** rank_one(N-1) = -1.0 ! Ok. ! rank_one(N+1) = -2.0 ! Not ok. END SUBROUTINE proc END PROGRAM equiv [/fortran]
"Recent" (for several years now) versions of gfortran support the C interoperability features of F2003. It tends to be one of the earlier F2003 features implemented by vendors because it is pretty useful.
I can accept that there might be too few F2003 compilers out there to adopt it today, but to be limiting yourself to F77 twenty years after F90 (or even F95) was published, given the language improvements made with that version of the standard, is crazy.
- 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