2011-10-04 135 views
1

我試圖編譯我的程序與英特爾Fortran編譯器Linux(版本12.0.3)和我得到這個錯誤:Fortran編譯錯誤

buggy.f90(206): error #6219: A specification expression object must be a dummy 
argument, a COMMON block object, or an object accessible through host or use 
association [SPECTRUM] 
    type(spect)      :: spectrum 
----------------------------------------^ 

這是一個模塊內。 type(spect)來自另一個模塊,其中我use在一開始的麻煩模塊。這是一些代碼;更多細節可以在下面找到。

module non_buggy 

    implicit none 

    type axis 
     character(len=6) :: nucleus 
     integer   :: num_data_points 
     real    :: spectral_width 
    end type axis 

    type spect 
     integer     :: num_dim 
     type(axis), allocatable :: axes(:) 
     real, allocatable  :: intensity(:) 
     character(len=10)  :: type = '' 
    end type spect 

    type(spect), target :: spectrum ! might this be a cause of error? 

    contains 
    ! ... 
end module non_buggy 


module buggy 

    use non_buggy 

    implicit none 

    contains 

    subroutine no_problem_here() 

     type(spect) :: spectrum ! compiles beautifully 
     ! ... 
    end subroutine no_problem_here 

    subroutine problem() 
     type(spect) :: spectrum ! does not compile, but no error if I change the variable name 
     ! ... 
    end subroutine problem 
end module buggy 

我看了一下是什麼錯誤意味着,但我有什麼,我在我的代碼正在做的,不適用的印象 - 沒有數組邊界是在這些線路中指定。由於錯誤消失了,如果我將第二次出現的spectrum重命名爲其他內容,我想知道該問題是否與模塊non_buggy中的模塊變量spectrum有關(但是,即使我註釋掉該行,錯誤仍然存​​在其中聲明瞭模塊變量)。如果Fortran專家能夠澄清這個問題,我將非常感激。

非常感謝!

+1

該錯誤是在別的地方。我甚至嘗試編譯你的模塊。但我相信問題的根源在別的地方。因爲你分享代碼的和平沒有任何問題。如果可能,請更多代碼。 – Wildcat

+0

@kemiisto你是對的!我發現這個問題,它在編譯器指出的線下面三行。我確實在數組邊界聲明中使用了'頻譜'的一部分 - 當然,編譯時沒有指定大小... – canavanin

回答

2

在代碼示例中,我看不到任何錯誤,即使它很容易出錯(例如,在例程no_problem_here和問題中)聲明具有與全局變量相同名稱(頻譜)的局部變量模塊non_buggy)。

你使用什麼編譯器?我用ifort 11.1和gfortran 4.7.0編寫了樣例,沒有任何問題(只是在註釋模塊non_buggy的關鍵字CONTAINS時,因爲ifort抱怨在「contains」和「end module」之間沒有指令)。

+0

感謝您的時間和精力!我發現了這個問題;它與模塊變量名稱相同的局部變量無關,它只是我有點愚蠢......(請參閱原始問題下的我的評論) – canavanin

4

無法在linux和osx上使用ifort 11進行重現。我沒有ifort 12,所以我無法驗證,但這裏的要點是,您要從模塊中導出spectrum,這很可能是個壞主意。請務必在模塊中使用關鍵字private,並明確公開您想要發佈的內容。

如果你想讓光譜成爲一個模塊變量(我不明白,爲什麼你會?你期望一個且只有一個光譜?你確定嗎?)你也可以考慮如果你需要一個save關鍵字來保存這些值。

最後,你掩蓋了一個模塊變量。 Idiotic Fortran沒有命名空間的概念。如果你從另一個模塊中的某個模塊中摧毀了所有的東西,就會污染你的命名空間,而且你很可能最終會遇到這些情況。在某些情況下支持子程序導入,以限制損害(儘管它變得不太通信)。保持你的模塊的最小值,當你這樣做的時候,要麼用一個唯一的前綴作爲它們的前綴,要麼就是不要使用它們,並且在你的代碼的類OOP佈局中自我約束。

模塊應該是無狀態的。您可以獲得靈活性並減少多線程頭痛。

+0

只需添加一項:您還可以在「使用」語句中使用唯一的子句,以包含您真正想要的內容,例如類型本身。 – haraldkl

+0

@Stefano:你能否澄清一下「在某些情況下支持子程序導入,以限制損害(儘管它變得不那麼通信)」? – bdforbes

+1

@bdforbes:你可以在每個例程中使用你需要的東西,而不是在模塊級使用模塊。它可能更加多餘,並且你失去了交流的機會,因爲現在,爲了看到你的模塊依賴於什麼,你需要打開單個例程,而不是僅僅查看模塊的初始部分。 –