我有一个派生类型t_file
,其中有一个终结例程close
,它只是将“终结”写入屏幕。
还有一个函数返回类型t_file
的实例。
该程序的输出是
Finalization.
Finalization.
Just opened
2000
Done.
我有两个问题:
Just opened
输出之前发生 我的编译器是英特尔(R)Visual Fortran Composer XE 2011 12.1.3526.2010。
以下是代码:
module m_file
implicit none
type t_file
integer::iu=1000
contains
final::close
end type
contains
function openFile() result(f)
implicit none
type(t_file)::f
f%iu = 2000
end function
subroutine close(this)
implicit none
type(t_file)::this
write(*,*) 'Finalization.'
end subroutine
end module
program foo
use m_file
implicit none
type(t_file)::f
f = openFile()
write(*,*) 'Just opened'
write(*,*) f%iu
write(*,*) 'Done.'
read(*,*)
end program
答案 0 :(得分:5)
这种行为也让我感到惊讶。我一直在掌握Fortran的新(-ish)OO功能,但还不需要编写最终的程序。我认为我可以为这种行为提供各种解释。
在Modern Fortran Explained的p282上,作者写道:
当一个可终结的对象即将停止存在时(例如,通过 被解除分配或执行
return
声明),决赛 以对象作为其实际参数调用子例程。这个 当对象传递给intentout
虚拟对象时也会发生 参数,或者是内在函数左侧的变量 转让声明。在后一种情况下,最后的子程序是 在右侧的表达式之后调用 已评估,但在将其分配给变量之前。
在我看来,好像你正在触及本段中提到的两种情况。当函数Finalization
中名为f
的实体在从该函数返回时将超出范围时,您将获得第一个openFile
。
当作业范围中的变量Finalization
用于作业f
的 lhs 时,您获得第二个f = openFile()
。
从这一切结论来看,我得出的结论是,你没有看到程序范围内f
的过早定型,而是略有不同。
我并不完全相信这就是正在发生的事情,我无法想出为什么语言的行为应该如此。我有点惊讶,现在我已经调查过了,当程序结束并且Finalization
超出范围时,你没有收到第三条f
消息。
幸运的是,真正的Fortran大师很快就会过去并启发我们所有人。
答案 1 :(得分:0)
高性能标记给出的小修正:第一次完成实际上是程序范围中的变量f。这可以通过让最终例程打印此%iu并将程序范围中的f%iu设置为某个任意值来简单地看到。