Reputation: 2553
I found that the array size can be defined by parameters but not variables. An example is given below to explain what I am saying.
1st Example - Not working:
integer :: narr=100
integer, dimension(narr) :: Total
2nd Example - Working:
integer, parameter :: narr=100
integer, dimension(narr) :: Total
In the 1st example, I expect the dimension
can use the variable narr
as narr
is defined FIRST. But I realized that this may not be true as the creation of variable may not follow the order of my code lines. Maybe this is only what a person with Python background only would think so.
In the 2nd example, things work perfectly.
I speculate that the difference is related to WHEN the variable and constant are created. Can someone explain the mystery inside it?
Upvotes: 2
Views: 1402
Reputation: 1585
In your examples, since integer, dimension(narr) :: Total
does not have an allocatable
or pointer
attribute, it is either a static array or an automatic array, depending on the context (I'm leaving out assumed shape array because the question is specifically about defining arrays). In either case, its size must be a compile time constant or a dummy argument. In the first example, narr
is neither which makes it invalid Fortran. In order to use narr
as a non-constant variable to specify the size, you would need to declare Total
as a dynamic array by including the allocatable
or pointer
attribute. This might have a performance penalty depending on the situation, but it allows more flexibility in how and where the array bound is defined.
Here are some of the common ways to define static and dynamic arrays in Fortran:
! Static
call test_fixed_size()
call test_size_parameter()
! Dynamic
call test_allocatable()
call test_pointer()
call test_automatic(10)
contains
subroutine test_fixed_size()
integer :: array(10)
array = 1
end subroutine test_fixed_size
subroutine test_size_parameter()
integer, parameter :: size = 10
integer :: array(size)
array = 1
end subroutine test_size_parameter
subroutine test_allocatable()
integer, allocatable :: array(:)
integer :: narr = 100
allocate(array(narr))
array = 1
end subroutine test_allocatable
subroutine test_pointer()
integer, pointer :: array(:) => null()
integer :: narr = 100
allocate(array(narr))
array = 1
deallocate(array)
end subroutine test_pointer
subroutine test_automatic(size)
integer, intent(in) :: size
integer :: array(size)
array = 1
end subroutine test_automatic
end program
(I'm leaving out more modern features here such as automatic allocation on assignment.)
Upvotes: 4