1QuickQuestion
1QuickQuestion

Reputation: 417

Gfortran -Wuninitialized flag misses variable in do loop

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

Answers (2)

JohnE
JohnE

Reputation: 30444

Characteristics of presumed bug

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:

  1. inside do loop
  2. variable appears on both the right and left hand side (e.g. 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)

Option 1 for catching undeclared reals

shell commands:

> gfortran -finit-real=snan main.f90
> ./a.out

output:

noninit =               NaN

Notes:

  1. This does not give a compiler warning, nor do it cause a run time error, but it initializes NONINIT as a NaN instead of zero, which is much more likely to tip you off to the problem here, but obviously it will depend on what exactly your program does later on with NONINIT.
  2. Because this option explicitly initializes reals as NaNs, it negates any warning for reals that you would have gotten from -Wuninitialized, as no reals will now be uninitialized! But you should still get a warning for most uninitialized integers.

Option 2 for catching undeclared reals

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:

  1. The important option with -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.
  2. The -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

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

Related Questions