Parameter in call for array size

Hi everyone,

I have difficulties doing something that should be simple. I want to define in a main program a parameter, then pass it to a subroutine where an array is created using this parameter , example below :slight_smile:

program A
x=5
call B(x)

  "and inside B"
    real*8 Y(X)

It is not working for some reason, can anyone tell me the way to do it?

Thanks a lot

Romain

You do not say what is not working and your excerpt is rather terse. I include a working example below:

! autoarray.f90 --
!     Illustrate how to create automatic arrays
!
program autoarray
    implicit none

    integer :: x

    x = 5

    call print_size( x )

contains
subroutine print_size( y )
    integer, intent(in)                  :: y
    real(kind=kind(1.0d0)), dimension(y) :: array

    write(*,*) 'Size: ', size(array)

end subroutine print_size
end program autoarray

Notes:

  • Automatic arrays like this are useful, but you can get into trouble if they are too large - stack overflow. Alternatives then: use allocatable arrays.
  • real*8 is not part of the Fortran standard, though it is a popular extension
  • The dimensions of an array of any kind must be integers
  • It helps if you use “implicit none”, even in such tiny and temporary programs like the one above :slight_smile:

If your compiler is Fortran 90 or better, have a look at https://web.stanford.edu/class/me200c/tutorial_90/07_arrays.html to learn about allocatable arrays. If you only have Fortran 77, then know that there are no dynamic arrays. You would have to declare an array at least as big as 5 elements and pass the array to the subroutine. You could also pass the size.

program a
double precision a(5)
call b(a,5)
stop
end
subroutine b(a,c)
integer c
double precision a(c)

return
end

you can see some examples in Arrays - Fortran Programming Language

Thanks enveryone, i managed to find the way to do it, in fact the size of the array was computed in the subroutine where i needed it, i just had to compute it in my main program and then pass the integer to the subroutine

Just to expand on Arjen’s notes:
There are 3 main types of locally defined arrays in Fortran that allocate memory usage.
Local arrays : real :: array(parameter_size) ! where parameter_size is constant or integer parameter
Automatic arrays : real :: array(arg_size) ! where arg_size is an integer argument to the routine.
Allocatable arrays : real, allocatable :: array( : ) ! where arg_size is defined in/for the ALLOCATE statement

Local and automatic arrays are allocated an address and space on the stack, while allocatable arrays are allocated on the heap.
Local and automatic arrays can be more efficient for small arrays, but this does not apply for larger arrays. If the array size exceeds a memory page, there is little performance advantage. Large could be n > 100.

Many will be familiar with the stack overflow web site, which derives it’s name from the stack curse of always being too small. Using local or automatic arrays always have the danger of being too big for the stack, while allocatable arrays are a much more robust option.
If the size can ever be uncertain or large, use allocatable, else one day you will get a stack overflow crash and the error message can be very cryptic.
To me the stack design for most operating systems of not providing an extendable stack is their worst/laziest design failure. Over the years, I have spent too much time chasing these errors, typically at a time when I have a report or production deadline and didn’t have the time to go back and maintain the code.

Also note the administrator can increase the allowed stack size, which on 64-bit systems has little or no significant cost. HPC Administrators almost always greatly increase the limits from the defaults if the vendors have not already done so.

This increase is severely limited on 64-bit OS, typically to 2 or 4GBytes.
We will have to wait and see if a full 64-bit OS will eventuate.

The x in Romain’s program is not a parameter though Romain thought it was. In Fortran that word is used
when defining a constant that cannot be altered subsequently in the program, e.g.
integer,parameter:: x=5