2012-06-25 76 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設置爲某個任意值來簡單地看出。

相關問題