兩個地圖之間的概念差異到非常顯着的實際差異。
INCLUDE行在源代碼級別運行 - 它實現簡單(「啞」)文本包含。如果沒有任何特殊的處理器對include文件中的「文件名」的解釋(實際上並不需要文件),那麼完整的源代碼可以非常容易地由程序員手動拼接在一起並送入編譯器,而沒有區別永遠在源的語義。包含的來源沒有單獨的真實解釋 - 其含義完全取決於引用包含來源的包含行的上下文。
模塊在程序高得多的實體級別運行,即在編譯器正在考慮源實際描述的事物的級別。一個模塊可以獨立於下游用戶進行編譯,一旦編譯完成,編譯器就可以準確知道模塊可以提供給程序的內容。
通常什麼人使用包括線是希望做的是什麼模塊實際上是設計做。
示例問題:
由於實體聲明可以分佈在多個語句通過包括源描述的實體可能不是你所期望的。考慮到包括以下來源:
INTEGER :: i
在隔離它看起來像這樣聲明的名稱i
爲一個整數標量(或者一個功能誰知道呢?!)。現在考慮下面的範圍,包括上面:
INCLUDE "source from above"
DIMENSION :: i(10,10)
i
現在是一個等級×2個陣列!也許你想讓它成爲一個指針?一個ALLOCATABLE?一個虛假的爭論?也許這會導致錯誤,或者它可能是有效的來源!將隱式類型輸入到混合中以真正複合潛在的樂趣。
一個模塊中定義的實體的是「完全」由模塊限定。可以改變特定於使用範圍的屬性(VOLATILE,可訪問性等),但基本實體保持不變。名稱衝突被明確地調出,並且可以使用USE語句中的重命名子句輕鬆解決。
Fortran語言對語句排序的限制(規範語句必須可執行語句之前,等等)。包括的來源也受限於這些限制,在包含的範圍內,不是來源定義點的範圍內的。
充分混合與一些完全鈍角錯誤消息語句函數定義(規範的部分)和賦值語句(可執行部分)之間源歧義或更糟的是,無聲接受的錯誤代碼的編譯器。
有在哪裏出現引用模塊USE語句的要求,但實際的模塊程序單元的源完全獨立於它的使用點的。
有花式到跨相關程序共享一些全局狀態和要使用包括哪些內容?讓我向您介紹常見塊以及相關聯的序列關聯概念...
序列關聯是早期底層Fortran處理器實現的不幸流血,這是一種容易出錯,不靈活的反優化時間錯誤。
模塊變量使得公共塊及其相關的弊病完全不必要的。
如果您使用的是包含行,請注意您並未實際包含常用過程的來源(第一段中的建議只會導致編譯器語法錯誤的消失) 。你通常會做的是包含描述該過程的接口的源代碼。對於任何非平凡的過程,描述界面的源與過程的完整源不同 - 意味着您現在需要維護同一事物的兩個源代表。這是一個容易出錯的維護負擔。
如前所述 - 編譯器自動獲取一個模塊程序的界面的知識(編譯器的知識是「明確的」,因爲它居然看到了程序的代碼 - 因此稱爲「顯式接口」)。程序員不需要做更多的事情。
上述結果是,除非有很好的理由相反(可能存在循環或過度依賴),否則不應使用外部子程序- 基本的出發點應該是一切在模塊或主程序中。
其他海報提及模塊的源代碼組織的好處 - 包括能夠將相關的程序和其他「東西」到一包,有超過的內部實現細節可訪問控制。
我接受有包括線按問題的第二段的有效使用 - 在大型模塊的尺寸變得笨重。 F2008通過子模塊解決了這個問題,這也帶來了其他一些好處。一旦它們得到廣泛支持,應該放棄包含線的解決方法。
第二個有效的用法是克服通用編程技術(C++提供了什麼模板)缺乏支持 - 即操作涉及的對象類型可能會有所不同,但描述什麼的令牌序列對這些對象做的事情本質上是一樣的。在語言排序之前可能還需要十年左右的時間。
因此,在不同文件中分離子例程,然後在模塊中使用include,沒有缺點,對吧?我從來沒有聽說過子模塊。 – Nordico 2013-03-28 16:18:50
我只會考慮如果我有非常大的源文件或作爲傳統源遷移的一部分。如果可能的話,我會首先考慮將模塊分解成多個「子」模塊,然後將這些模塊與USE語句在父模塊中彙總在一起。但是,對於複雜的類型/過程依賴關係和/或Fortran的PUBLIC/PRIVATE輔助功能的工作方式,使用子模塊可能並不總是可行。您可能會發現,將模塊的源與INCLUDE行拼接在一起會混淆一些構建系統。 – IanH 2013-03-28 19:08:01