我正在研究一些代码,其中大量的变量被命名为abc1,abc2,abc3等。我想知道是否有人知道是否可以检查变量是否已经设置所以我可以循环他们中的一组很容易,例如
do lbl1 i = 1,100
IF (.NOT. NULL(abc&i)) THEN
print*, abc&i
END IF
lbl1..continue
任何信息都会很棒,非常感谢。
答案 0 :(得分:3)
我可以想到两个相关的选择:
-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
但是,正如手册页所说,“这会产生额外的代码,只能用于确定错误。”
答案 1 :(得分:3)
没有办法在Fortran中执行此操作:没有内在的检查变量已被定义(除了NULL()
以外,它只适用于指针)。你有三个真正的选择:
让编译器在编译时抱怨使用未定义的变量。如果打开标准警告,我想不出编译器没有这样做。例如,g95会说“警告(113):变量'a'在(1)使用但未设置”与-Wall
一起使用,但是如果没有则会生成产生随机垃圾的代码。这种方法的问题在于,并非所有这些情况都可以在编译时捕获 - 考虑在链接之前单独编译两个过程时将未定义的变量传递到子例程中。
使所有变量“无效”并在程序中检查。一种方法是手动(在代码中)这样做,但Pete使用编译器标志的第二种方法更好。这比实数更容易实现,因为您可以将未定义变量的无效值设置为NaN,如果在未定义的情况下使用它,则应该导致可执行文件停止运行(并提供有用的回溯)。对于g95 -freal=NaN
和-fpointer=invalid
非常有用,-finteger=-9999
可能有所帮助,但可能无法提供非常有用的调试信息。
通过监视可执行文件访问内存的方式在运行时进行检查。我在Valgrind's memcheck取得了成功。您需要做的就是使用调试标志(-g
或其他任何东西)编译代码,并通过带有--undef-value-errors=yes --track-origins=yes
的valgrind运行您的程序,您应该获得一个有用的报告,其中使用了未定义的变量以及每个变量的回溯案件。这将非常缓慢(跟踪所有内存访问并更新状态位图)但它确实有效,即使对于Fortran也是如此。
在实践中,1和2可以结合起来捕捉大多数情况 - 你真的希望大多数情况在尝试跋涉大量的valgrind输出之前进行整理,以寻找困难的情况。