Reputation: 89
I would like to understand the logic behind what I am going to show you.
If I have a 'module.f90':
module def_dimens
integer :: dimens=4
end module def_dimens
a 'subr.f90':
subroutine sub(X)
integer :: X
integer :: S(1:X*5)
S=1
print*,S
end subroutine sub
and a 'main.f90':
program test
use def_dimens
call sub(dimens)
end program test
by compiling gfortran module.f90 subr.f90 main.f90
and running the result there isn't any problem.
But with 'main2.f90' given by
program test
use def_dimens
integer :: A(1:dimens*5)
A=1
print*,A
end program test
and compiling gfortran module.f90 main2.f90
I have an error, so I have to use an allocatable array:
program test
use def_dimens
integer,allocatable :: A(:)
allocate(A(1:dimens*5))
A=1
print*,A
end program test
or I have to specify 'dimens' in the module as a parameter (but this is not useful for me, because in cases more complicated than this I would need a variable whose value is fixed by calling another subroutine before using it).
So my question is: Why is there such a difference? Why does gfortran complain when it has to declare an array in the main program by using a variable to fix its size, and instead there isn't any problem in doing that in a subroutine?
Upvotes: 3
Views: 1253
Reputation: 60008
To add to Kyle's answer, if you declare an array in a subroutine, which is not a dummy argument or it does not have the save
attribute, it is an automatic array
. It is allocated automatically each time when the subroutine starts to run. It is allocated according the value of the variables in the expression for it's shape. The values in the array are not preserved between calls.
Upvotes: 2
Reputation: 3264
You cannot have a statically defined array with a variable that the compiler thinks is variable. The error code (had you printed it) is pretty clear:
Error: the module or main program array
a
at (1) must have constant shape
The compiler does not know that dimens
is supposed to be constant. You can fix this by declaring dimens
as a parameter
:
module def_dimens
integer, parameter :: dimens=4
end module
Upvotes: 2