为什么在一个不相关的整数变量上调用 write 会释放 Fortran 中的无限多态指针?
Why does calling write on an unrelated integer variable deallocate an unlimited polymorphic pointer in Fortran?
我试图在无限多态 class 指针中保存任何类型的值,然后使用将 return 值作为特定类型的函数检索该值。到目前为止,我只为整数编写了代码。
文件名:pointers.f90
module pointers_example
contains
subroutine assign_int(pt,val)
class(*),allocatable,target :: temp
class(*),pointer,intent(inout) :: pt
integer,intent(in) :: val
allocate(temp,source=val)
pt => temp
end subroutine assign_int
pure function int_val(pt) result (val)
class(*),intent(in) :: pt
integer :: val
select type(v => pt)
type is (integer)
val = v
end select
return
end function int_val
end module pointers_example
program main
use pointers_example
implicit none
class(*),pointer :: pt
integer :: i = 10
integer :: output_unit = 6
call assign_int(pt,10)
write(output_unit,'("1. int_val(pt) = ",I2)') int_val(pt)
write(output_unit,'("i == int_val(pt)? ",L1)') int_val(pt) == i
write(output_unit,'("i = ",I2)') i
write(output_unit,'("2. int_val(pt) = ",I2)') int_val(pt)
write(output_unit,'("i == int_val(pt)? ",L1)') int_val(pt) == i
call assign_int(pt,10)
write(output_unit,'("3. int_val(pt) = ",I2)') int_val(pt)
end program main
当我用 gfortran 和 运行 编译它时,我得到的代码是:
$ gfortran -o pointers pointers.f90 ; ./pointers
1. int_val(pt) = 10
i == int_val(pt)? T
i = 10
2. int_val(pt) = **
i == int_val(pt)? F
3. int_val(pt) = 0
我不希望 int_val(pt) == ** 在第二种情况下。比较 int_val(i) == i 似乎表明它们都是在调用 write(output_unit,'("i = ", 之前具有相同值的整数I2)') i 但之后它们不一样了。似乎还有一个我不知道的打印到控制台之外的额外副作用。谁能解释这种行为?
感谢@evets 的回复,我找到了解决方案。我已将旧代码注释掉:
subroutine assign_int(pt,val)
!class(*),allocatable,target :: temp
class(*),pointer,intent(inout) :: pt
integer,target,intent(in) :: val
! allocate(pt,source=val)
! pt => temp
pt => val
end subroutine assign_int
本质上,临时 (temp) 指针正在被释放,因为它未保存且未由 assign_int 函数返回。根据 Fortran 标准“19.5.2.5:指针的关联状态在以下情况下变为未定义……(3) 指针的目标被解除分配,而不是通过指针”,pt 目标未定义。
我试图在无限多态 class 指针中保存任何类型的值,然后使用将 return 值作为特定类型的函数检索该值。到目前为止,我只为整数编写了代码。
文件名:pointers.f90
module pointers_example
contains
subroutine assign_int(pt,val)
class(*),allocatable,target :: temp
class(*),pointer,intent(inout) :: pt
integer,intent(in) :: val
allocate(temp,source=val)
pt => temp
end subroutine assign_int
pure function int_val(pt) result (val)
class(*),intent(in) :: pt
integer :: val
select type(v => pt)
type is (integer)
val = v
end select
return
end function int_val
end module pointers_example
program main
use pointers_example
implicit none
class(*),pointer :: pt
integer :: i = 10
integer :: output_unit = 6
call assign_int(pt,10)
write(output_unit,'("1. int_val(pt) = ",I2)') int_val(pt)
write(output_unit,'("i == int_val(pt)? ",L1)') int_val(pt) == i
write(output_unit,'("i = ",I2)') i
write(output_unit,'("2. int_val(pt) = ",I2)') int_val(pt)
write(output_unit,'("i == int_val(pt)? ",L1)') int_val(pt) == i
call assign_int(pt,10)
write(output_unit,'("3. int_val(pt) = ",I2)') int_val(pt)
end program main
当我用 gfortran 和 运行 编译它时,我得到的代码是:
$ gfortran -o pointers pointers.f90 ; ./pointers
1. int_val(pt) = 10
i == int_val(pt)? T
i = 10
2. int_val(pt) = **
i == int_val(pt)? F
3. int_val(pt) = 0
我不希望 int_val(pt) == ** 在第二种情况下。比较 int_val(i) == i 似乎表明它们都是在调用 write(output_unit,'("i = ", 之前具有相同值的整数I2)') i 但之后它们不一样了。似乎还有一个我不知道的打印到控制台之外的额外副作用。谁能解释这种行为?
感谢@evets 的回复,我找到了解决方案。我已将旧代码注释掉:
subroutine assign_int(pt,val)
!class(*),allocatable,target :: temp
class(*),pointer,intent(inout) :: pt
integer,target,intent(in) :: val
! allocate(pt,source=val)
! pt => temp
pt => val
end subroutine assign_int
本质上,临时 (temp) 指针正在被释放,因为它未保存且未由 assign_int 函数返回。根据 Fortran 标准“19.5.2.5:指针的关联状态在以下情况下变为未定义……(3) 指针的目标被解除分配,而不是通过指针”,pt 目标未定义。