Reputation: 417
Consider the following code:
PROGRAM TEST
IMPLICIT NONE
REAL:: noninit
noninit = noninit + 1
END PROGRAM TEST
If compiled with gfortran -Wall TEST.f90
a warning is correctly produced that ‘noninit’ is used uninitialized in this function [-Wuninitialized]
. Now consider the same code inside a do loop:
PROGRAM TEST
IMPLICIT NONE
REAL:: noninit
INTEGER:: ii
DO ii=1,10
noninit = noninit + 1 ! line 8
END DO
print *, "noninit = ", noninit
END PROGRAM TEST
When complied with the same command no warning of the uninitialized variable is produced. Could you please explain why this behavior is occurring and what I can do to fix it? My current solution is to use the -finit-real=snan
flag to create an easily followed trail of rubbish should a variable be uninitialized. Is there a better solution?
Upvotes: 3
Views: 763
Reputation: 30444
For starters it is helpful to narrow down exactly when this (presumed) bug occurs, and it seems to me that it happens if both these conditions hold:
x=x+1
)It does not appear to matter if variables are implicitly or explicitly declared, nor if they are integers or reals.
Hence, while this does appear to be a compiler bug, the circumstances are pretty narrow and -Wuninitialized
is going to catch the vast majority of errors with uninitialized variables, even inside of do loops.
Additionally, while -Wuninitialized
will fail in the above case, there are some other gfortran compiler flags that can be very helpful here, at least with respect to reals -- I don't know of any ways to catch integers. See below for a couple of options.
gfortran version = 5.5.0
(tested on linux system)
shell commands:
> gfortran -finit-real=snan main.f90
> ./a.out
output:
noninit = NaN
Notes:
-Wuninitialized
, as no reals will now be uninitialized! But you should still get a warning for most uninitialized integers.shell commands:
> gfortran -finit-real=snan -ffpe-trap=invalid,zero,overflow -g main.f90
> ./a.out
output:
Program received signal SIGFPE: Floating-point exception - erroneous
arithmetic operation.
Backtrace for this error:
#0 0x7FCE45AFC697
#1 0x7FCE45AFCCDE
#2 0x7FCE44FF73EF
#3 0x400818 in MAIN__ at main.f90:8
Floating point exception
Notes:
-ffpe-trap
is "invalid" but I included "zero" and "overflow" just because it seems that most people using this flag seem to use those three options.-g
flag is needed to see the line number causing the crash (it will still crash without -g
, but you won't have any idea what line it was).Upvotes: 3
Reputation: 60113
This is a particular defect in a particular compiler. I am not sure if it was reported to GCC bugzilla, as we suggested in the comments, or not.
Other compilers can catch it:
> ifort -g -warn -check noninit.f90
> ./a.out
forrtl: severe (194): Run-Time Check Failure. The variable 'test_$NONINIT' is being used in 'noninit.f90(7,5)' without being defined
Image PC Routine Line Source
a.out 0000000000402A2F Unknown Unknown Unknown
a.out 0000000000402992 Unknown Unknown Unknown
libc-2.26.so 00007F009F1A934A __libc_start_main Unknown Unknown
a.out 00000000004028AA Unknown Unknown Unknown
I bet NAG, with its rich debugging facilities, will catch it as well.
Upvotes: 1