Fortran 子例程中的 TARGET 属性
TARGET attribute in Fortran subroutines
(我用的是ifort 19.0.5.281)
在下面的测试代码中,在move_association
中我将POINTER作为INTENT(IN)并检查其关联状态,并将其关联更改为局部变量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
乍看之下,我认为应该存在一些问题,因为 Fortran 会在其结束时自动释放子例程的局部变量,从而使 cptr
失去其目标。但没想到 cptr
幸存下来,并且它的关联状态被检查为“关联”,如下输出。
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
我想可能还有其他规则,例如子程序中的局部 target
变量自动获得 save
属性等等,对吗?
最后你指针的状态是undefined
。不允许查询未定义状态的指针的关联状态,它包含一些垃圾。垃圾恰好是您不再有效的本地数组。您必须先将其无效或关联,然后再进行任何进一步的查询。
(我用的是ifort 19.0.5.281)
在下面的测试代码中,在move_association
中我将POINTER作为INTENT(IN)并检查其关联状态,并将其关联更改为局部变量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
乍看之下,我认为应该存在一些问题,因为 Fortran 会在其结束时自动释放子例程的局部变量,从而使 cptr
失去其目标。但没想到 cptr
幸存下来,并且它的关联状态被检查为“关联”,如下输出。
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
我想可能还有其他规则,例如子程序中的局部 target
变量自动获得 save
属性等等,对吗?
最后你指针的状态是undefined
。不允许查询未定义状态的指针的关联状态,它包含一些垃圾。垃圾恰好是您不再有效的本地数组。您必须先将其无效或关联,然后再进行任何进一步的查询。