View Single Post
  #24 (permalink)  
Old 09-27-2006, 04:26 PM
Gordon Sande
Guest
 
Posts: n/a
Default Re: Strange Porting Problem CVF to IVF, requesting help and ideas.

On 2006-09-27 12:47:42 -0300, nospam@see.signature (Richard E Maine) said:

> Jim Klein <jameseklein@earthlink.net> wrote:
>
>> I am thinking Qsave is going to be the immediate "fix". If it is, what
>> is the correct fix instead of "Q/save" ?

>
> The "correct" fix is in 2 parts - the save and the initialization. And
> it is different enough for common and everything else that I'll separate
> the 2 matters.
>
> COMMON
>
> Actually, if the variables in question are in common, as I think I saw
> mentioned (but I've been skimming most of this pretty quickly), you can
> get by without the save part. The standard technically requires it and
> there have been implementations where it actualy mattered, but I don't
> know of any curent implementations where save of common matters. Still,
> it is simple enough to do. Just add a statement
>
> save /whatever_the_common_name_is/
>
> I used to (pack when I used common) put this in the include file with th
> erest of the declarations of the things in the common, because it needs
> to appear everywhere that the common does.
>
> Then to initialize the variables in common....well... the standard
> answer involves block data. But that has so many caveats and
> complications that I cannot in good faith recommend it. And I sure can't
> explain all the issues that it raises here. I recommend instead, doing
> any intialization of variables in common with executable statements.
> Just use plain old ordinary assignment statements done early in the
> program. If there are many of them, you'd probably want to put them in a
> subroutine called early in the main program (or anywhere else that you
> are sure is before they are needed).
>
> NOT_COMMON
>
> This includes module variables also; they don't have the same issues as
> common.
>
> For each variable in question, give it the SAVE attribute, either with a
> separate save statement like
>
> save a,comma_separated,list,of,names,like_this
>
> or in the trype declaration like
>
> real, save :: x, y
>
> An alternative is to just use an unadorned
>
> save
>
> with nothing else in the statement (and no other save statements in the
> procedure either). This essentially says to save everything that can be
> sensibly saved in the routine. It is much like the common compiler
> switches, except that this one is in the code instead of on the command
> line, and this on eis standard.
>
> Realize, though, that saving alone is not sufficient to make things
> initialized. (It might have that effect in some compilers, but it
> certainly does not in the standard and is not portable). You have to
> also do the initialization. Either
>
> 1. Use a data statement, like
>
> data x/0.0/
>
> 2. Use an initializer in the type declaration like
>
> real, save :: x = 0.
>
> 3. Or just do it with executable assignment statements.
>
> Technically, initializing with a data statement or an initializer in the
> type declaration will also mak ethe variable saved "behind your back",
> but I prefer to make the save explicit.


I am sure Richard got tired of typing so he did not mention that SAVE
is two edged sword. (He must be a 60 word per minute touch typist given
the quantity of stuff he posts.)

There are good uses of SAVE like the internal state of a random number
generator or the tabulation of a repeatedly used function. Often the
saved value will be put in COMMON (or even better, a module) so the
intent is quite obvious. With static allocation of COMMON and MODULEs
the need for an explicit SAVE is more purist than practical.

And there are the poor uses which serve to mask the fact that there
is a lack of initialization of variables. Many vendors will provide
an initial value of zero so the first use appears OK but the final
value will be kept around and will then provide a nonzero starting
value for the next call. If that was intended as above then fine, but
all too often it was not the intended result and the computation only
appears to work. That may in fact be worse, in the long run, than it
failing early. This requires careful coding for routines that have
and initialization call that uses part of the code and then working
calls that use other parts of the code. Easy to blunder and hard to
spot as you "know" what it is intended to do. If you have the wrong
mental model (i.e. you do not actually understand it) of how DATA
and initializers work then SAVE will not be of any use and will just
be a bug hiding out in the open.



Reply With Quote