Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29246 Discussions

Unallocated array in rhs of assignment

John4
Valued Contributor I
946 Views

Hi, is the following code standard conforming?

[fortran]integer, allocatable :: array(:)
array = [array, 1, 2]
array = [array, 3]
print *, array
end[/fortran]
I mean, does the standard allow an unallocated array to be part of an array expression? Compiling with /stand and /assume:realoc_lhs doesn't issue any warning, and there's no runtime error either.

0 Kudos
6 Replies
IanH
Honored Contributor III
946 Views
With /check:all and 11.1.065 I see an appropriate runtime error.

0 Kudos
mecej4
Honored Contributor III
946 Views
Beyond the scope of your question, if what you wanted to do was to build up the array in pieces, code such as this may be considered:

[fortran]program talloc

   integer, allocatable :: array(:)
 
  if(.not.allocated(array))allocate(array(0))

  array = [array, 1, 2]
  array = [array, 3]

  print *, array

end program talloc
[/fortran]
0 Kudos
John4
Valued Contributor I
946 Views

I'm actually trying to avoid having to check the allocation status every time one entry needs to be added. I already have a subroutine that does just that:

[fortran]subroutine expand(array, idx, istat)
    integer, allocatable, intent(INOUT) :: array(:)
    integer, intent(OUT) :: idx, istat
    integer, allocatable :: aux(:)
    integer :: sz

continue
    idx = -1

    if (ALLOCATED(array)) then
        sz = SIZE(array)
        call MOVE_ALLOC(array, aux)

        allocate (array(1:sz + 1), STAT = istat)
        if (istat /= 0) then
            call MOVE_ALLOC(aux, array)
            return
        endif

        array(:sz) = aux

        sz = sz + 1
        deallocate (aux, STAT = istat)
    else
        sz = 1
        allocate (array(1), STAT = istat)
        if (istat /= 0) return
    endif

    idx = sz
end subroutine[/fortran]

That's why I only asked if it was standard conforming. IanH's answer seems to confirm that the code is illegal.

0 Kudos
Les_Neilson
Valued Contributor II
946 Views
if (allocated(array)) then
sz = size(array) +1 ! new size
allocate(aux(sz), stat=istat)! allocate bigger array
if (istat == 0) then ! ok ?
aux(1:sz-1) = array ! then copy old values tobigger array
aux(sz) = 0 ! initialise new elements
call move_alloc(aux, array)!"rename" aux as array
endif
else
...
endif

only need one move_alloc and don't need a deallocate

Les
0 Kudos
John4
Valued Contributor I
946 Views

If you look carefully, you'll notice that the second MOVE_ALLOC is applied only in case of error (which is highly unlikely). The explicit deallocation of aux is just a precaution (since some compiler flags might affect automatic deallocation).

0 Kudos
Les_Neilson
Valued Contributor II
946 Views
Ah. OK

Les
0 Kudos
Reply