1

我有一个t_file带有终结例程的派生类型,close它只是将“终结”写入屏幕。还有一个函数返回 type 的实例t_file。这个程序的输出是

Finalization.
Finalization.
Just opened
     2000
Done.

我有两个问题:

  • 为什么最终确定发生在输出之前Just opened
  • 为什么最终确定会发生两次

我的编译器是 Intel(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
4

2 回答 2

5

这种行为也让我感到惊讶。我已经掌握了 Fortran 的新(-ish)OO 功能,但还不需要编写最终程序。我认为我可以为这种行为提供某种解释。

在Modern Fortran Explained的p282 上,作者写道:

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

在我看来,您似乎同时遇到了本段中提到的两种情况。当函数内Finalization命名的实体在从该函数返回时将超出范围时,您将获得第一个。fopenFile

Finalization当程序范围内的变量f用于赋值的lhs时,您将获得第二个f = openFile()

从所有这些中,我得出结论,您并没有看到f程序范围内的过早完成,而是有些微妙的不同。

我并不完全相信这就是正在发生的事情,而且我想不出为什么语言的行为应该如此的充分理由。我有点惊讶,现在我已经调查过了,Finalization当程序结束并f超出范围时,您没有收到第三条消息。

运气好的话,一位真正的 Fortran 大师很快就会过去并启发我们所有人。

于 2012-06-25T14:17:16.260 回答
0

对High Performance Mark给出的答案的小幅更正:第一个最终确定实际上是程序范围内的变量f。这可以通过让最终例程打印 this%iu 并将程序范围内的 f%iu 设置为某个任意值来简单地看到。

于 2013-03-05T07:34:43.207 回答