From: Gordon Sande on
On 2010-07-05 00:03:46 -0300, "Lynn McGuire" <lmc(a)winsim.com> said:

>> Something I recommended a while back is to find a compiler that
>> allows default initializations to arbitrary bit patterns. Then you
>> can set all variables that are otherwise not initialized the right
>> way (i.e. with save statements, data statements, and normal
>> assignments) to various values (large positive or negative values
>> for integers, signaling/quiet NaNs or positive or negative HUGE()
>> for floating point) and watch where the program errs. You can work
>> through your program one routine at a time or in blocks of routines
>> as appropriate. Hopefully, the bad code is limited and localized.
>
> I think that I want to stay with our current compiler until we get everything
> to working without /save. That way we have a baseline and can run two
> debug sessions, one with /save and one without.

You may also run into the situation where the progrmmer assumed (incorrectly)
that the zero initialization would happen on each entry but instead the
values are those left over from the previous entry. So you have been living
with a (hopefully minor) bug for all this time. Fixing things to assign to
zero will change things. Your problem will be to figure out which is right.
Simply keeping things the same as they were may involve preserving some number
of bugs!

The thing to worry about is the bug that has been producing plausible
answers that have become the accepted answers.

>> Perhaps you can identify it as mostly being written by a single bad
>> programmer, and track it down that way. When your code is finally
>
> Over 100 programmers wrote our software. Maybe 200 over the 40+
> years.
>
> Thanks,
> Lynn


From: mecej4 on
Lynn McGuire wrote:

> As many have advised on this board, we are looking to remove the /save
> compiler option from our compiles. The /save option initializes all local
> variable to zero and saves their values between subroutine calls. Does
> anyone have experience doing this and have any advice ? We have about
> 600,000 lines of code and 100,000 local variables to initialize.
>
> I was wondering what would be the best procedure for doing this:
> 1. initialize all local variables to zero in a data statement
> 2. initialize all local variables to zero in a statement at the beginning
> of the
> subroutine (my favorite)
> 3. something else ?
>
> Thanks,
> Lynn

Lynn: given the size of the task facing you, it is more important that you
start out with a full understanding of the implications of choosing each of
the alternatives that you have listed, instead of adopting one of them on
the basis of recommendations alone.

Here is an example that illustrates my point:

--------------------------------
program undefvar

integer :: ivar

call sub
ivar=-100 ! diversion
call sub
write(*,'(/,I4)')ivar ! diversion

end program undefvar

subroutine sub()

integer :: iv ! should have been initialized to -10 and 'save'd
if(iv < 0)iv=-iv
iv=iv+10
write(*,*)iv
return

end subroutine sub
--------------------------------

Let us assume that the original programmer's intention was to initialize iv
to -10 in the subroutine, and have iv retain its value from one subroutine
call to the next. The bugs consist of not doing the initialization and not
specifying the 'save' attribute. The programmer's expected results from the
program:

20
30

-100


If you use your alternatives 1 or 2, you will be deceiving yourself. Try
your alternatives on this silly test program. The program may run, but not
as intended. The results may be wrong, but it may evade you to recognize
that they are faulty.

Likewise, if you use a compiler's option to do zero-initialization using a
compiler switch, or add the 'save' attribute to the variable iv, the
modified program will still not function correctly, since the intended
initialization to -10 has not been implemented. Beyond the
common "initialize to zero" feature, no compiler can read the programmer's
intentions. Along the same lines, what are proper initial values for
LOGICAL and CHARACTER variables, for which "initialize to zero" makes no
sense?

Now, for your big application, consider that, instead of the integer iv, the
ideal-gas constant R is the one that is not initialized wherever it is
needed, and imagine the consequences.

What recourse is there left? I recommend that you use a compiler that will
most effectively help you hunt down instances of uninitialized variables.
Lahey/Fujitsu, NAG and, on Windows, Salford/Silverfrost compilers have good
capabilities of this sort. NAG is especially good in pinpointing bugs with
respect to INTENT(OUT) variables.

Compilers that set out to produce fast executables are not necessarily
suited for the task before you.

HTH.

-- mecej4
From: Lynn McGuire on
> Now there are cases where choice 2 is superior. But they are all cases
> where the code does not need SAVE. In particular, if you have code that
> assumes zero initialialization, does not need SAVE, and might get
> converted to being invoked multiple times in a single program, then
> choice 2 does the needed zero initialization for each invocation.
> Parallelization is a prime area where this could be relevant.

I think that our code needs zeroing upon EACH entry of our subroutines.
I have been trying this out and have gotten several benchmark files to run
to completion now by adding the zeroing of a few key variables (the indexes
for the arrays variables have been killers).

I doubt that we have very many actual variables to be SAVEd that have
not already been marked as such.

Thanks,
Lynn


From: Lynn McGuire on
> You may also run into the situation where the progrmmer assumed (incorrectly)
> that the zero initialization would happen on each entry but instead the
> values are those left over from the previous entry. So you have been living
> with a (hopefully minor) bug for all this time. Fixing things to assign to
> zero will change things. Your problem will be to figure out which is right.
> Simply keeping things the same as they were may involve preserving some number
> of bugs!
>
> The thing to worry about is the bug that has been producing plausible
> answers that have become the accepted answers.

That is where our engineering expertise comes in and we can tell the change
is for the better or for the worse.

Thanks,
Lynn


From: dpb on
Lynn McGuire wrote:
....

> I think that our code needs zeroing upon EACH entry of our subroutines.
> I have been trying this out and have gotten several benchmark files to run
> to completion now by adding the zeroing of a few key variables (the indexes
> for the arrays variables have been killers).
....

If that's the case, it's been wrong w/ the /SAVE option because it does
_NOT_ do that at all.

>> type wat.for

program wat
x = 1.0

call foo(x)
call foo(x)
end

Subroutine foo(x)

x = x+1.

print *, y

y = y+1.0
End


C:\Temp> wfl386 /save wat.for
Watcom F77/32 Compile and Link Utility Version 11.0
Copyright by Sybase, Inc., and its subsidiaries, 1990, 1997.
All rights reserved. Watcom is a trademark of Sybase, Inc.
wfc386 wat.for /save
Watcom FORTRAN 77/32 Optimizing Compiler Version 11.0 2010/07/05 18:15:38
Copyright by Sybase, Inc., and its subsidiaries, 1984, 1997.
All rights reserved. Watcom is a trademark of Sybase, Inc.
wat.for: 11 statements, 72 bytes, 1 extensions, 0 warnings, 0 errors

WATCOM Linker Version 11.0
Copyright by Sybase, Inc., and its subsidiaries, 1985, 1997.
All rights reserved. Watcom is a trademark of Sybase, Inc.
loading object files
searching libraries
creating a Windows NT character-mode executable

C:\Temp> wat
0.0000000
1.0000000

C:\Temp>

--