Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

keeping array limits in fortran during subroutine call

I have the following program

module test
contains
   subroutine foo()
      integer, allocatable :: a(:)
      allocate(a(-5:5))
      call bar(a)
      print *, a
   end subroutine
   subroutine bar(a)
      integer, intent(out) :: a(:)
      a = 0 
      a(-4) = 3  ! here
      a(2) = 3   
   end subroutine
end module

program x
   use test
   call foo()
end program

In the line marked with "here" I am doing something wrong. The fact is that when I receive the array a (in the caller allocated from -5 to +5), the callee uses conventional numbering (1 to n), meaning that assigning -4 I am doing an out of boundary assignment. How can I instruct the compiler that, within the bar routine, the numbering of the a array must be the same as in the caller ?

like image 829
Stefano Borini Avatar asked Dec 06 '10 12:12

Stefano Borini


3 Answers

The type of dummy argument that you are are using in the subroutine, with the dimension specified with a colon, is called "assumed shape". This name is the clue -- Fortran passes only the shape and not the lower and upper bounds. The lower bound is assumed to be one unless you override it as shown in the answer by kemiisto. If the lower bound is not fixed, you can pass an argument to use as the lower bound.

Later addition: a code example if the lower dimension isn't known at compile time:

subroutine example (low, array)
   integer, intent (in) :: low
   real, dimension (low:), intent (out) :: array
like image 111
M. S. B. Avatar answered Oct 12 '22 14:10

M. S. B.


There are two common options:

  • As kemisto wrote, you pass a second argument. This was common in F77-style code. You can not use the LBOUND trick! It has to be passed as an integer.
  • You declare the argument to be a pointer, which includes the entire array descriptor. Then the bounds of the array in the subroutine are the same as in the calling scope. Of course you may lose on optimization this way.
like image 31
U.B. Avatar answered Oct 12 '22 13:10

U.B.


How can I instruct the compiler that, within the bar routine, the numbering of the a array must be the same as in the caller ?

Not sure but according to the standard you can specify the lower bound for an assumed-shape array.

subroutine bar(a)
      integer, intent(out) :: a(-5:)
like image 2
Wildcat Avatar answered Oct 12 '22 13:10

Wildcat