2016-11-19 33 views
1

我在理解爲什麼在子例程中聲明的變量(i)在包含的子例程中可見,但這對於函數(fie)編譯錯誤。我搜索了一個答案,並試圖查看是否可以在Fortran 95標準中找到某些東西,但徒勞無功。所包含子例程中變量和函數的作用域規則

我寫了一個小例子程序:

program pgm 
    call a 
end 

subroutine a 
    implicit none 
    integer :: i 
    double precision :: fie 

    i = 7 
    call b 
    !write(*,*) fie(9) 

contains 
    subroutine b 
    double precision :: x 
    !double precision :: fie 

    x = i 
    x = x + fie(i) 
    write(*,*) x 
    end subroutine 
end subroutine 


double precision function fie(ii) 
    implicit none 
    integer, intent(in) :: ii 

    fie = ii 
end function 

當在cygwin下與gfortran編譯此(gfortran 5.4.0)我得到以下錯誤消息:

$ gfortran aa.f90 
aa.f90:20:15: 

    x = x + fie(i) 
       1 
Error: ‘fie’ at (1) is not a function 

當啓用的任一程序編譯並正確運行的註釋行。

使用英特爾編譯器時(英特爾Fortran 12.1.7.367,確實很舊),我看到類似的錯誤消息。

它看起來像fie必須在包含的例程中可用或必須在包含子例程中使用,但正如所說我無法在網絡或Fortran 95標準中找到答案(或者我可能沒有找到合適的詞)。

任何解釋?

+0

我知道使用模塊會更好,但它是現有代碼庫的一部分,其中部分擴展(由其他人使用)。 – albert

回答

2

最簡單的解決辦法是使用

double precision, external :: fie 

外部屬性(也可以通過external語句中指定)說:這是一個過程,我不聲明一個局部變量。

對於沒有將external解釋爲函數聲明的聲明,函數引用必須存在於函數體中。內部功能不計算。因此編譯器創建了一個名爲fie的本地雙精度變量。

感謝對IanH的相關標準規則(從2008年的Fortran(16.5.1.4p5),但Fortran 95的將有一個相當的):如果一個帶有隱式接口的外部或啞過程是

通過主機關聯訪問 ,則主機作用域單元中應具有EXTERNAL 屬性;如果它作爲 中的函數調用,則內部作用域單元及其類型和類型參數應在主機作用域單元中建立的 。如果該作用域單元顯式聲明它們,調用 函數,從模塊訪問該函數,或者從其主機訪問函數 ,那麼具有EXTERNAL屬性的函數 的類型和類型參數將建立在範圍 單元中。類型和類型參數建立了 。

當然顯式接口(最好使用模塊)比外部函數好得多。

+0

我忘了'external'的可能性在Fortran95標準中的段落「14.6.1。3主機協會「存在,但在這方面對我來說不太清楚。 – albert