blackbourna
blackbourna

Reputation: 1243

Check if a variable has been declared using Fortran 77?

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

Answers (2)

Andrew Walker
Andrew Walker

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:

  1. 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.

  2. 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.

  3. 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

Pete
Pete

Reputation: 10680

I can think of two related options:

  1. When the program starts up, set all of these variables to an invalid value (-9999). Check the value at run-time.
  2. Some compilers have flags to do just this. For example, the IBM compiler lets you initialize to a specific hex value:
   -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

Related Questions