Global variable initial value?

I have a variable defined within a module, called unitz.

I have a line early on in the code that states kunitz = unitz yet no where do I have an assigned value to unitz.

If I output the value of unitz at differing points within the code, even at the very start of the program, I am informed that unitz is equal to 0.

Does Fortran default to zero for any variable defined?

No, compilers may do so, and there are compiler flags specifically for this problem. But it is recommended to initialise all values manually:

module test
    implicit none

    integer, save, public :: unitz = 0
end module test
1 Like

Thank you. I hasten to add that this is not originally my code and I am now exploring it in incredibly fine detail; hence finding this anomaly.

I am now trying to identify specifically what variables are required and what their initial values should be.

Thank you again.

Depending on the size of the code and the number of variables used in it, scanning the code for initializations can take an unacceptably long time. If so, use a compiler that provides facilities for trapping variables that are used before being initialized.

My exact intention!

First, I need to work on the small element I am working on at present; since I got to the middle of it before finding this issue. :slight_smile:

save won’t hurt here but is double unnecessary

  1. All variables in a module are automatically saved
  2. Variables declared with initialization also acquire save attribute
1 Like

Certainly, but it is a common pitfall in Fortran, and explicit is better than implicit.

I am planning to tweet the following:

To catch the use of uninitialized variables, initialize real variables
to signalling NaN and integers to -999 and trap NaNs at run time with

gfortran -ffpe-trap=invalid,overflow -finit-real=snan -finit-integer=-999 -fbacktrace a.f90

Also see Detection of Uninitialized Floating-Point Variables in Intel® Fortran.

If the code a.f90 is

program main
implicit none
integer :: i
real :: x(2)
print*,i
print*,sum(x)
end program main

compiling on WSL2 with the gfortran command above gives at run time

        -999

Program received signal SIGFPE: Floating-point exception - erroneous arithmetic operation.

Backtrace for this error:
#0  0x7fdda118d700 in ???
#1  0x7fdda118c8a5 in ???
#2  0x7fdda0fc020f in ???
#3  0x55a02f2b2287 in MAIN__
#4  0x55a02f2b2302 in main
Floating point exception

and something similar on Windows.

The NAG compiler (nagfor) has an option -C=undefined that does extensive run-time checking for uses of uninitialized variables. It has a couple of caveats (no inter-operating with C and no coarray features), and a few bugs I’ve been reporting, but I’ve found it quite helpful in finding some subtle bugs even beyond your run-of-the-mill oops.

You might want to add -g so you get symbol names on tracebacks, and mention
-Wuninitialized on gfortran, particularly making note that -Wuninitialized and -finit-real=snan are mutually exclusive (well, actually I think using -finit-real=snan defines variables so -Wuninitialized has nothing left to find). A lot of users of gfortran just do “man gfortran” or “gfortran --help” and often are not aware of the many other options available, many of which are displayed with “gfortran -v --help”, so it is easy to miss options llike -Wuninitialized, as it does not show with a simple “gfortran --help”. When we used to make local compiler changes we always set negative indefinite as the default where available, and use to create a universal config file for the Intel compiler to help detect uninitialized variables; particularly since we had a number of codes that had originated on VAX/VMS where (if I remember correctly) the Fortran compiler initialized everything to zero; so I am all for users using those options during development; but if you have large arrays there can be a significant cost to initializing them that you might want to avoid in a production release.

A footnote. There seems to be a regresssion on a bug reported long ago with -Wuninitialized and I/O. If you do a “gfortran -Wuninitialized” on

program testit
   a=a+1
end program testit

it produces a warning, but

program testit
   write(*,*)a
   a=a+1
end program testit

produces no warning. Thought that was fixed a VERY long time ago.

Re presence of I/O statement causing failure to detect uninitialized variable:

I do not know which Gfortran bug ID you refer to, but there is one still active bug report, and the test code in it is very similar to your example.

That one covers it. The bug I was referring to is not that incorrect executables are generated, but that the -Wuninitialized option does not warn about uninitialized variables that appear in I/O statements; which your link reports. Thanks for the link; that saves me from searching for/reporting the same bug.