2011-05-24 45 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 

然而,由于该名男子页说,“这会产生额外的代码,应该只用于错误的决心。 “

相关问题