我正在研究一些代碼,其中大量的變量被命名爲abc1,abc2,abc3等。我想知道是否有人知道是否有可能檢查變量是否已設置,以便我可以循環他們很容易,例如檢查是否使用Fortran 77聲明瞭一個變量?
do lbl1 i = 1,100
IF (.NOT. NULL(abc&i)) THEN
print*, abc&i
END IF
lbl1..continue
任何信息都會很棒,非常感謝。
我正在研究一些代碼,其中大量的變量被命名爲abc1,abc2,abc3等。我想知道是否有人知道是否有可能檢查變量是否已設置,以便我可以循環他們很容易,例如檢查是否使用Fortran 77聲明瞭一個變量?
do lbl1 i = 1,100
IF (.NOT. NULL(abc&i)) THEN
print*, abc&i
END IF
lbl1..continue
任何信息都會很棒,非常感謝。
在Fortran內部沒有辦法做到這一點:沒有固有的方法來檢查變量是否已被定義(除了NULL()
並且只適用於指針)。你有三個真正的選擇:
讓編譯器抱怨在編譯時使用未定義的變量。我想不出一個編譯器,如果你打開它的標準警告就不會這樣做。例如,g95會說「警告(113):在(1)的變量'a'被使用但未設置」與-Wall
一起使用,但只會產生會產生隨機垃圾的代碼,如果不是的話。這種方法的問題是並非所有這些情況都可以在編譯時捕獲 - 考慮在鏈接之前分別編譯這兩個過程時,將未定義的變量傳遞給子例程。
使所有變量「無效」,並在程序中檢查。一種方法是手動(在代碼中)執行此操作,但Pete使用編譯器標誌的第二種方法更好。由於可以將一個未定義的變量的無效值設置爲NaN,這會導致可執行文件停止運行(並提供有用的回溯),如果在未定義的情況下使用該文件,則會更加容易。對於g95 -freal=NaN
和-fpointer=invalid
很有用,-finteger=-9999
可能會有所幫助,但可能不會提供相當有用的調試信息。
通過監視可執行文件訪問內存的方式在運行時執行檢查。我已經成功使用了Valgrind's memcheck。所有你需要做的就是編譯帶有調試標誌(-g
或其他)的代碼,並通過valgrind與--undef-value-errors=yes --track-origins=yes
運行你的程序,你應該得到一個有用的報告,哪些變量使用未定義的每個案例的回溯。這將非常緩慢(所有內存訪問都得到跟蹤,並且狀態位圖已更新),但它確實可行,即使對於Fortran也是如此。
在實踐中1和2可以結合起來,趕上大多數情況下 - 和你真的想大多數情況下試圖涉水大規模Valgrind的輸出尋找困難的情況下才整理出來。
我能想到的兩個相關選項:
-qinitauto=<hex_value> | -qnoinitauto Initializes each byte or word of storage for automatic variables to the specified hexadecimal value <hex_value>. This generates extra code and should only be used for error determination. Default: -qnoinitauto
然而,由於該名男子頁說,「這會產生額外的代碼,應該只用於錯誤的決心。 「