Search code examples
pointersfortranfortran90

TARGET attribute in Fortran subroutines


(I used ifort 19.0.5.281)

In following test code, in move_association I take POINTER as INTENT(IN) and check its association state, and change its association to local variable array(4,4).

module mod_test

    implicit none

contains

    subroutine write_matrix_2d(a)

        implicit none
        real, intent(in) :: a(:,:)
  
        ! local variables
        integer :: i, j

        do i = lbound(a,1), ubound(a,1)
            write(*,*) ( a(i,j), j = lbound(a,2), ubound(a,2) )
        enddo
  
    end subroutine

(*) subroutine move_association(a)

        implicit none
        real, pointer, intent(inout) :: a(:,:)

        ! local
        real, target  :: array(4,4)

        array = -1

        if ( associated(a) ) then
            print *, "POINTER is associated"
            a => array
        else
            print *, "POINTER is NOT associated"
            a => array
        endif

    end subroutine

end module

program test

    use mod_test

    implicit none

    real, dimension(3,3), target  :: ct(3,3)
    real, dimension(:,:), pointer :: cptr(:,:)

    ct = 1
    !cptr => ct(2:3,2:3)

    write(*,*)
    write(*,*) 'ct'
    call write_matrix_2d(ct)

    write(*,*)
    write(*,*) 'cptr before'
    call write_matrix_2d(cptr) 

    write(*,*)
(*) call move_association(cptr)

    write(*,*)
    write(*,*) 'cptr after'
    call write_matrix_2d(cptr)

    write(*,*)
    if ( associated(cptr) ) then
        print *, " cptr associated "
    else
        print *, " cptr not associtated "
    endif

end program

At glance, I thought there should be some problem since Fortran automatically deallocates subroutine's local variable at the end of it making cptr to loss its target. But unexpectedly cptr survived and also its association state is checked as "associated" as the following output.

 ct
   1.000000       1.000000       1.000000    
   1.000000       1.000000       1.000000    
   1.000000       1.000000       1.000000    
 
 cptr before
 
 POINTER is NOT associated
 
 cptr after
  -1.000000      -1.000000      -1.000000      -1.000000    
  -1.000000      -1.000000      -1.000000      -1.000000    
  -1.000000      -1.000000      -1.000000      -1.000000    
  -1.000000      -1.000000      -1.000000      -1.000000    
 
  cptr associated 

I suppose there might be additional rules such that local target variable inside subroutine automatically gets save attribute and so on, is this right?


Solution

  • The status of your pointer at the end is undefined. You are not allowed to inquire the association status of a pointer with undefined status, it contains some garbage. The garbage happens to be your local array that is no longer valid. You have to nullify it or associate it yourself before any further inquiry.

    See also http://www.cs.rpi.edu/~szymansk/OOF90/bugs.html#5