请考虑以下类结构,其中涉及三个单独的模块:
!-----------------------文件a.f
module parent_body_mod
type :: face
class(parent_body), pointer :: bPtr
end type
type, abstract :: parent_body
integer i
type(face) :: f
end type
end module parent_body_mod
!------------------------文件b.f
module body_mod
use parent_body_mod
type, extends(parent_body) :: body
end type
interface body
procedure :: new_body
end interface
contains
function new_body() result(b)
type(body), target :: b
b%i = 123
b%f%bPtr => b
end function
end module body_mod
!---------------------------文件c.f
module body_group_mod
use body_mod
type :: body_group
type(body), allocatable :: b
end type
interface body_group
procedure :: new_body_group
end interface
contains
function new_body_group() result(bg)
type(body_group) :: bg
allocate(bg%b)
bg%b = body()
end function
end module body_group_mod
!-------------------主程序
use body_group_mod
type(body_group) :: my_bg
my_bg = body_group()
print *, my_bg%b%f%bPtr%i
end
!--------------------------------------
预期输出为123,而实际输出为随机。该代码使用ifort版本18.0.1进行编译。请注意,当使用“ body”类本身时,不会发生相同的问题,即以下方法可以正常工作:
type(body), allocatable :: my_b
allocate(my_b)
my_b = body()
print *, my_b%f%bPtr%i ! This produces 123 as expected.
感谢您的帮助。
答案 0 :(得分:3)
代码不符合要求。
与过程未保存的局部变量关联的指针在过程执行完成时变得不确定(F2008 16.5.2.5(5))。函数b
中的函数结果new_body
被认为是局部变量(F2008 1.3.154.1),因此指针组件b%f%bPtr
在函数调用后变得不确定。
函数结果与其他本地未保存的变量相比有一些特殊之处,因为它们的值可用的时间长于变量的存在时间-有关讨论,请参见F2008注12.41。
解决问题的另一种方法是,使用语句bg%b = body()
,左侧的主体与右侧的主体是不同的对象。该分配只是复制右侧对象的值-一旦分配完成,右侧对象将不复存在。没有代码可以说,当传送主体对象的值时-指针组件需要更新以引用分配给它的左侧变量。另外请注意,左侧bg%b
没有TARGET属性-因此,无论如何都无法将指针与之有效关联。