2012-06-25 79 views
1

我有一个派生类型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 

回答

5

这种行为让我吃惊了。我已经开始熟悉Fortran的新(Oish)OO功能,但尚未编写最终程序。我认为我可以为这种行为提供一些解释。

Modern Fortran Explained作者P282写:

当终结对象即将停止存在(例如,通过 被释放或从return语句的执行),则最终 子程序是用该对象作为其实际参数进行调用。当对象传递给虚拟 参数或者是内部 赋值语句左侧的变量时,也会发生此 。在后一种情况下,最后一个子程序是 ,在右边的表达式已被求值 后,但在将其分配给变量之前,调用该子程序。

它在我看来好像是在击中本段提到的两种情况。当函数openFile中名为f的实体即将从该函数返回时超出范围时,将获得第一个Finalization

你得到第二Finalization时在程序范围内的变量f是在LHS分配f = openFile()使用。

从所有这些我得出结论,你没有看到在程序范围内f过早完成,但有些细微的不同。

我并不完全相信这是正在发生的事情,我想不出为什么语言的行为应该保持原样。我有点惊讶,现在我已经仔细研究过了,当程序结束并且f超出范围时,您没有收到第三个Finalization消息。

幸运的是,真正的Fortran大师将会很快过去,并启发我们所有人。

+1

我认为你的解释非常好。我也期待第三个。我认为设计是合乎逻辑的,因为在所有这些情况下你都可能需要它。 –

+0

不幸的是,我想为我完成关闭文件单元的工作,所以它在我使用它之前就已经关闭了单元。我想我可以不做最终定稿。 – bdforbes

+0

另一方面,在整个计划的其他部分,它实际上运行良好,并没有提前完成。尽管如此,我还没有能够提炼出一个这样的例子。 – bdforbes

0

对高性能标记给出的答案进行微小修正:第一次定稿实际上是程序范围中的变量f。这可以通过让最终例程打印这个%iu并将程序范围中的f%iu设置为某个任意值来简单地看出。

相关问题