Reputation: 1243
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.
Upvotes: 2
Views: 4232
Reputation: 2471
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.
Upvotes: 3
Reputation: 10680
I can think of two related options:
-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
However, as the man page says, "This generates extra code and should only be used for error determination."
Upvotes: 3