2011-05-24 85 views
2

我正在研究一些代碼,其中大量的變量被命名爲abc1,abc2,abc3等。我想知道是否有人知道是否有可能檢查變量是否已設置,以便我可以循環他們很容易,例如檢查是否使用Fortran 77聲明瞭一個變量?

do lbl1 i = 1,100 
    IF (.NOT. NULL(abc&i)) THEN 
     print*, abc&i 
    END IF 
    lbl1..continue 

任何信息都會很棒,非常感謝。

回答

3

在Fortran內部沒有辦法做到這一點:沒有固有的方法來檢查變量是否已被定義(除了NULL()並且只適用於指針)。你有三個真正的選擇:

  1. 讓編譯器抱怨在編譯時使用未定義的變量。我想不出一個編譯器,如果你打開它的標準警告就不會這樣做。例如,g95會說「警告(113):在(1)的變量'a'被使用但未設置」與-Wall一起使用,但只會產生會產生隨機垃圾的代碼,如果不是的話。這種方法的問題是並非所有這些情況都可以在編譯時捕獲 - 考慮在鏈接之前分別編譯這兩個過程時,將未定義的變量傳遞給子例程。

  2. 使所有變量「無效」,並在程序中檢查。一種方法是手動(在代碼中)執行此操作,但Pete使用編譯器標誌的第二種方法更好。由於可以將一個未定義的變量的無效值設置爲NaN,這會導致可執行文件停止運行(並提供有用的回溯),如果在未定義的情況下使用該文件,則會更加容易。對於g95 -freal=NaN-fpointer=invalid很有用,-finteger=-9999可能會有所幫助,但可能不會提供相當有用的調試信息。

  3. 通過監視可執行文件訪問內存的方式在運行時執行檢查。我已經成功使用了Valgrind's memcheck。所有你需要做的就是編譯帶有調試標誌(-g或其他)的代碼,並通過valgrind與--undef-value-errors=yes --track-origins=yes運行你的程序,你應該得到一個有用的報告,哪些變量使用未定義的每個案例的回溯。這將非常緩慢(所有內存訪問都得到跟蹤,並且狀態位圖已更新),但它確實可行,即使對於Fortran也是如此。

在實踐中1和2可以結合起來,趕上大多數情況下 - 和你真的想大多數情況下試圖涉水大規模Valgrind的輸出尋找困難的情況下才整理出來。

3

我能想到的兩個相關選項:

  1. 當程序啓動時,所有這些變量設置爲無效值(-9999)。在運行時檢查該值。
  2. 一些編譯器有這樣做的標誌。例如,IBM的編譯器可以讓你初始化到一個特定的十六進制值:
-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 

然而,由於該名男子頁說,「這會產生額外的代碼,應該只用於錯誤的決心。 「

相關問題