If you want to initialize an array to have zero elements, something like
integer,allocatable :: ints(:)
ints=[] ! WILL NOT WORK
ints=[ints,10] ! add element to array
ints=[ints,20] ! add element to array
ints=[ints,30] ! add element to array
write(*,*) ints
end
will produce a compiler error along the lines of
Error: Empty array constructor at (1) is not allowed
In Fortran a general rule is that the right-hand side of an assignment must be evaluated first, and the simple expressions "[]" is incomplete because there is not way to determine the type of the expression. Fortran does not have a NULL type. So you need to use something like
ints=[integer ::]
! ^^^^^^^^^^
or
allocate(ints(0))
For character variables something like
chars=[character(len=0) :: ]
or
allocate(character(len=0) :: chars(0))
would allocate zero character elements of zero length.
The following example program creates a file with various length lines and then reads it in to an array, allocating and reallocating the array that starts off with zero elements until the file has been read into the array. The length of the elements is adjusted to the longest length read so far with each read.
Assuming you have a small file called "lines.txt" (note this does a lot of reallocations and is storing the file in memory) here is an example program that starts with an array called WORDS which is initially allocated as having zero character elements of zero length and ends up having the entire contents of the file "lines.txt".
program dusty_corner
implicit none
character(len=:),allocatable :: words(:)
character(len=4096) :: line ! ASSUMPTION that LINE is large enough for any input file
integer :: big=0,ios,ipos,iposback=1,ilen
words=[character(len=0)::] ! Allocate zero-size array
!!words=[] ! is not standard because cannot tell type of a null array, but intuitively seems like
!! ! it should be a special case where LHS is used to determine type.
open(10,file='lines.txt')
INFINITE: do
read(10,'(a)',iostat=ios)line
if(ios.ne.0)exit INFINITE
write(*,*)'LINE=',trim(line)
! get length of last line read ASSUMPTION: reading from standard disk file
inquire(10,pos=ipos) ! get position of file being read
ilen=ipos-iposback-1 ! find change from last read, which should be length of line read
iposback=ipos ! store end of last line
big=max(big,ilen) ! length of longest line read so far
words=[ CHARACTER(LEN=big) :: words, line ] ! words reallocated to LEN=BIG and new line added
enddo INFINITE
write(*,*)'FINAL ARRAY' ! should print entire file
write(*,'("[",a,"]":)')words
end program dusty_corner
Because there is no builtin "empty array" object, I've tried to mimic it with some user-defined type (just for fun). -- spectrum
module emptyarray_m implicit none private public empty, assignment(=) type Empty_t endtype type(Empty_t) empty !! singleton interface assignment(=) module procedure ints_from_empty, strings_from_empty endinterface contains subroutine ints_from_empty( x, emp ) integer, allocatable, intent(inout) :: x(:) type(Empty_t), intent(in) :: emp if ( allocated( x ) ) deallocate( x ) allocate( x( 0 ) ) end subroutine strings_from_empty( x, emp ) character(:), allocatable, intent(inout) :: x(:) type(Empty_t), intent(in) :: emp if ( allocated( x ) ) deallocate( x ) allocate( character(0) :: x( 0 ) ) end end
program main use emptyarray_m implicit none integer, allocatable :: ints(:) character(:), allocatable :: strs(:) ints = empty call check_ints() ints = [1,2,3] call check_ints() ints = empty call check_ints() strs = empty call check_strs() strs = [ "apple", "orang", "banan" ] call check_strs() strs = empty call check_strs() contains subroutine check_ints() print *, "ints: size = ", size(ints) if ( allocated(ints) .and. size(ints) > 0 ) print *, "ints: val = ", ints end subroutine check_strs() integer k print *, "strs: size = ", size(strs) if ( allocated(strs) .and. size(strs) > 0 ) then print *, "strs: val = ", ( strs( k ) // " ", k=1,size(strs) ) print *, " len_elem = ", len(strs( 1 )) endif end end
Results with gfortran-7.2:
ints: size = 0 ints: size = 3 ints: val = 1 2 3 ints: size = 0 strs: size = 0 strs: size = 3 strs: val = apple orang banan len_elem = 5 strs: size = 0
So, if there is a language support, it might be not too difficult to think of a common "empty array" thing (though not sure if it is sufficiently useful).