Search code examples
arraysfortranallocation

Allocation of zero-sized arrays and use in array constructors


In the following code, I am trying to allocate an empty array of size 0 and add more elements afterward by using automatic reallocation:

integer, allocatable :: a(:)

allocate( a(0) )        ! Line 1
print *, size( a )
print *, "a(:) = ", a

a = [ a, 1 ]
print *, "a(:) = ", a

a = [ a, 2 ]
print *, "a(:) = ", a

!! Error
! a = []
! a = [ integer :: ]

This code gives the expected result (e.g., with gfortran or ifort -assume realloc_lhs)

           0
 a(:) = 
 a(:) =            1
 a(:) =            1           2

Here I have three questions:

  • First of all, is it OK to allocate zero-sized arrays such as allocate( a( 0 ) )?
  • If we omit such an explicit allocation, will a(:) be automatically initialized to a zero-sized array? (Indeed, the code seems to work even if I comment out Line 1.)
  • Is it no problem to include zero-sized arrays in an array constructor like a = [a, 1]? (I also tried using an empty array constructor like a = [] or a = [integer::], but they did not compile and so seem to be not allowed.)

Edit

If I uncomment a = [] in the above code, gfortran5.3 gives the error message:

Error: Empty array constructor at (1) is not allowed

but if I uncomment only the line a = [ integer :: ], it worked with no problem! Because I initially uncommented both lines at the same time, I misunderstood that the both ways are illegal, but actually the latter seems OK (please see @francescalus answer).


Solution

  • 1 Yes. Fortran is cool with 0-sized arrays.

    2 a(:) is not an array but an array-section (albeit one which comprises the whole array). Automatic reallocation is not defined to work on array sections, so

    allocate(a(0))
    a(:) = [1 2 3]
    

    doesn't work. In my test the code compiled and executed but a was left with 0 size.

    As to whether the code a = [a,1] ought to work if a has not previously been allocated (to 0- or any other size) my reading of the standard is that this is not standard conforming and that your compiler (mine too) is in error. I expect this is a mis-reading of the standard on my part. Perhaps someone else will come along and explain properly.

    3 Yes

    allocate(a(0))
    a = [a, 1]
    

    is fine, it conforms to the standard and works as you'd expect. As you've noticed an empty array constructor is not permitted in an automatic allocation