odd bug, VMS 7.1/alpha, GCG 8.1, MAP

mathog at seqaxp.bio.caltech.edu mathog at seqaxp.bio.caltech.edu
Fri May 22 18:24:19 EST 1998

In article <6k27an$4mi at gap.cco.caltech.edu>, mathog at seqaxp.bio.caltech.edu writes:
>Anybody else out there still running GCG 8.1 - on OpenVMS 7.1 (alpha)?
>I've hit a very odd bug, not quite sure in what (GCG, compiler, linker, VMS?).
>Can anybody else verify this behavior?
>$ for/Align/Extend_Source/NoList/Warning=All gensource:map.for
>$ sharelink map
>$ mmm:==$current_disk:[current_directory]map.exe

Ok folks, I tracked it down, and it is *ugly* and, unfortunately, pervasive.

In many places in MAP (and many other GCG 8.1 programs) one finds code like:  

       If ( .not.CLGetOldFName('INfile1', 1, SeqName) .and.
     &      .not.CLNoInteract()                            ) then
!*         do something here
       End If

The problem is that the Fortran standard apparently does not specify the
order in which the two functions will be evaluated, nor does it guarantee
that both will be evaluated, if after evaluating the first one, the result
of the second cannot change the result.  (This from Steve Lionel, who is
pretty much the final word on these matters.)  Older versions of Digital
Fortran on Alpha (and apparently every other Fortran compiler that GCG runs
on) did it in the left to right order, first CLGetOldFName, and then, if
necessary, CLNoInteract.  Unfortunately, newer versions of Digital Fortran
are now doing it CLNoInteract, then, if necessary, CLGetOldFName.

So, if you put /DEFAULT on the command line, .not. CLNoInteract comes up 
FALSE, and .FALSE. .AND. anything, is .FALSE., which the compiler 
has allowed for, so the program never executes CLGetOldFName.  Making the
/infile=whatever on the command line perfectly useless.  /NOOPT doesn't
disable this optimization.

Unfortunately, the current version of the compiler cannot even issue 
warnings about this, so all you can do is manually go through the code
searching for this sort of structure (and I found a lot of them) and 
rewrite them the way they should have been in the first place, ie:

	If ( .not.CLGetOldFName('INfile1', 1, SeqName)) then
	  If (.not.CLNoInteract() ) then
!*         do something here
	  End If
	End If

Note that the following is no better than the original:

	isinter = .not. CLNointeract()
	If ( .not.CLGetOldFName('INfile1', 1, SeqName) .and. isinter)then
!*         do something here
	End If

because the program will check isinter, and again bail before it executes

The good news is that this bug is only uncovered when you recompile any of
the Fortran modules - the older object files still work. 

They may have cleaned this up in GCG 9.0 or later, but in that case it 
would hardly matter, since you probably wouldn't have the source
code to modify.


David Mathog
mathog at seqaxp.bio.caltech.edu
Manager, sequence analysis facility, biology division, Caltech 

More information about the Info-gcg mailing list

Send comments to us at biosci-help [At] net.bio.net