Since I started the whole affair I would like to summarize a
little bit (and then shut up :)
I think my criticism of the current implicit save rule for initialized
variables still holds.
My remedy for it, well that's a different matter. As Richard Maine has
pointed out there are too many users that rely upon it for historical
reasons which make this change too radical to be possible.
So I have to retract my proposed change of rules.
I certainly don't take backward compatability lightly, but I think it is
used too often to kill any improvement. It seems to me that users of other
languages take a more relaxed position when it comes to improving the
language, they update their code and get on with life.
Why was the current rule adopted? The modern statement like
INTEGER :: I=0
is a replacement for the F77 construct
INTEGER I
DATA I/0/
as Walt Brainerd pointed out. Since that F77 form was used together with
an implicit save it was used for the new form as well. OK, that explains
it and I have my reason.
But I think it was a very bad design choice since the equally possible form
INTEGER, SAVE :: I=0
would have been much clearer and more in line with the default that all
variables become undefined, unless ... (see standard). A default should be
a default, any deviation should be explicitly marked, that would be good
language design. Several comments from others indicate that the current F90
rule is misleading and got bitten.
A mandatory explicit SAVE statement would also have left the door open for
a simple initial value treatment like
INTEGER :: I=0 ! Caution hypothetical semantics now
that would be valid upon each entry into a procedure, more in line with other
languages, programmer's expectations, etc. Unfortunately that door is now shut
as well. I am very wary about some proposals to allow such an initial value
but with an extra attribute like AUTOMATIC (from C++), etc. because the
language gets bigger, from a design point of view it is bad to have to achieve
a default behaviour with a non-default statement.
I hope future language modifications will be taken with a bit more consideration
for good design. It is not always easy in a language as old as Fortran.
Some pointed out that there was a CONVENTION that all variables in procedure
were saved upon exit, though the standard did and does not support this.
This convention is bad, at least from today's point of view for several very
strong reasons. It inhibits a good modular structure, since variables become
persistent when they should not (and results may depend on the order of
execution), techniques like recursion, parallel computing, object-oriented
programming would be severely handicapped by such a default rule.
My Recommendations:
* Never ever assume SAVE semantics.
* Use SAVE on all initialized variables to make the implicit SAVE explicit.
* Use an explicit SAVE attribute, but NOT a global SAVE statement.
* Use IMPLICIT NONE, global PRIVATE in MODULEs
* More generally, never use global Attribute statements (except PRIVATE)
but use them in the type declaration.
* Never assume the compiler initializes variables for you (even to Zero)
Do it yourself.
* Update your old code if you can.
* Throw out the old F66 and F77 rules, the world is changing, rules
are changing, stay ahead of the game as much as possible.
* Read some good books on good programming practices
(Metcalf's Effective Fortran 77 still has a lot to say,
Steve McConnell's Code Complete is more general not geared towards Fortran)
* Spread the message
I hope you all learned something, at least I did.
Thanks to all for your comments.
Cheers, WWS
-----------------------------------------------------------------------
| Werner W Schulz |
| Dept of Chemistry email: [log in to unmask] |
| University of Cambridge Phone: (+44) (0)1223 336 502 |
| Lensfield Road Secretary: 1223 336 338 |
| Cambridge CB2 1EW Fax: 1223 336 536 |
| United Kingdom WWW: |
-----------------------------------------------------------------------
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|