检查变量是否已使用 Fortran 77 声明?
我正在编写一些代码,其中大量变量被命名为 abc1、abc2、abc3 等。我想知道是否有人知道是否可以检查变量是否已设置,以便我可以循环访问一组变量他们很容易,例如
do lbl1 i = 1,100
IF (.NOT. NULL(abc&i)) THEN
print*, abc&i
END IF
lbl1..continue
任何信息都会很棒,非常感谢。
I'm working on some code where a great deal of the variables are named abc1, abc2, abc3, etc. I'm wondering if anyone knows if it's possible to check if the variable has been set so I can loop through a group of them easily, e.g.
do lbl1 i = 1,100
IF (.NOT. NULL(abc&i)) THEN
print*, abc&i
END IF
lbl1..continue
Any info would be great, thanks very much.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在 Fortran 中无法做到这一点:没有内部函数来检查变量是否已定义(
NULL()
除外,并且仅适用于指针)。这里有三个真正的选择:让编译器抱怨在编译时使用未定义的变量。我想不出如果您打开标准警告,编译器不会执行此操作。例如,当与
-Wall
一起使用时,g95 会显示“警告 (113):(1) 处的变量‘a’已使用但未设置”,但如果不使用,则只会生成产生随机垃圾的代码。这种方法的问题在于,并非所有此类情况都可以在编译时捕获 - 当您在链接之前分别编译两个过程时,请考虑将未定义的变量传递到子例程中。使所有变量“无效”并在程序中检查这一点。一种方法是手动(在代码中)执行此操作,但 Pete 使用编译器标志的第二种方法更好。对于实数,这比整数更容易,因为您可以将未定义变量的无效值设置为 NaN,如果在未定义的情况下使用它,这将导致可执行文件停止运行(并提供有用的回溯)。对于 g95
-freal=NaN
和-fpointer=invalid
很有用,-finteger=-9999
可能有帮助,但可能不会那么有帮助调试信息。通过监视可执行文件如何访问内存来在运行时进行检查。我已经成功使用 Valgrind memcheck。您需要做的就是使用调试标志(
-g
或其他)编译代码,并通过 valgrind 使用--undef-value-errors=yes --track-origins= 运行您的程序是的,您应该得到一份有用的报告,其中包含未定义的变量以及每种情况的回溯。这将非常慢(所有内存访问都会被跟踪并更新状态位图),但它确实有效,即使对于 Fortran 也是如此。
在实践中,1 和 2 可以结合起来捕获大多数情况 - 并且您确实希望在尝试涉足大量 valgrind 输出寻找困难情况之前先解决大多数情况。
There is no way to do this from within Fortran: there is no intrinsic to check that a variable has been defined (other than
NULL()
and that only works for pointers). You have three real options here:Get the compiler to complain about the use of undefined variables at compile time. I cannot think of a compiler which does not do this if you turn on its standard warnings. For example, g95 will say "Warning (113): Variable 'a' at (1) is used but not set" when used with
-Wall
but will just produce code which produces random rubbish if not. The problem with this approach is that not all such cases can be caught at compile time - think about passing an undefined variable into a subroutine when you compile the two procedures separately before linking.Make all variables "invalid" and check for this in the program. One way would be to do this by hand (in the code) but Pete's second approach using a compiler flag is better. This is easer with reals than integers because you can set the invalid value of an undefined variable to NaN which should cause the executable to stop running (and give a useful backtrace) if it's used without being defined. For g95
-freal=NaN
and-fpointer=invalid
are useful,-finteger=-9999
may help but probably will not give quite as helpful debugging info.Do the checks at runtime by monitoring how the executable is accessing memory. I've had success with Valgrind's memcheck. All you need to do is compile the code with debugging flags (
-g
or whatever) and run your program via valgrind with--undef-value-errors=yes --track-origins=yes
and you should get a useful report of which variables were used undefined with backtraces for each case. This will be quite slow (all memory access gets tracked and a bitmap of status updated) but it does work, even for Fortran.In practice 1 and 2 can be combined to catch most cases - and you really want most cases sorted out before trying to wade a massive valgrind output looking for the difficult cases.
我可以想到两个相关选项:
然而,正如手册页所说,“这会生成额外的代码,并且只能用于错误确定。”
I can think of two related options:
However, as the man page says, "This generates extra code and should only be used for error determination."