Separation of declaration and initiation of variables

My historical understanding of FORTRAN is that COMMON initially had global scope. I have never understood why The Fortran Committee wanted to change that. It was a fundamental concept in early FORTRAN. There was a short time when overlay linkers changed that, but that was a specific change.
The change to BLOCKDATA is an interesting one, as it did have a specified use, but is now being removed.
“integer :: i = 1” was introduced with F90; I thought to simplify the duplicity of DATA statements.
This is different to “integer, parameter :: i = 1”, as for a parameter, the value can not be changed.
If you remove the implied save from “integer :: i = 1”, the statement no longer has any meaning.
In it’s current form, I don’t see where the problem is. I don’t see it as error prone, although I have been using Fortran for a long time.
There are other Fortran code constructs that are more error prone, such as the duplicity of INTERFACE and also the move to voluminous declaration constructs where it is unclear what the compiler should do with them, eg should the compiler enforce INTENT(out) by deleting the input contents or is it a comment to say it can provide a changed result, especially if the change depends on other IF conditions.

The trend to voluminous complexity of Fortran declarations should be resisted.

No, not at all.

The whole idea behind getting rid of “implicit save” will be to invalidate definition via assignment in a declaration statement unless the SAVE attribute is applied explicitly.

This conforming code per current standard

   integer :: i = 1
end

will be invalidated with a processor being required to detect and report the error in a future revision of the standard.

Whereas code with an explicit ‘SAVE’ attribute will be unaffected e g.,

   integer, save :: i = 1
end

Then the idea will be to introduce “initialization” semantics into the language along with (possibly some new) simple syntax

   integer :: i {1}
end

that supports the “creature comforts” of practitioners and which heralds a new path, unencumbered by any legacy considerations such as DATA which adversely affected what got introduced starting Fortran 90 revision.

If we refer to the history, it is worth noting that the current implicit save for entities initialized in type declaration is not equivalent to placing such an entity in a DATA statement in F77. The latter was implicitly SAVEd only if not redefined.

Why do you say so? Both DATA and initialization in a type declaration give the concerned variable the SAVE attribute. Redefinition of such variables, if done, has the same effect regardless of which method of initialization was used. Here is a example:

program tst
implicit none
integer i1,i2 ! not initialized
!
call suba(i1,i2)
print 10,1,i1,i2
call subb(i1,i2) ! both arguments are redefined
print 10,2,i1,i2
call suba(i1,i2)
print 10,3,i1,i2
10 format('After call ',i,' i1,i2 = ',2i4)
end program

subroutine suba(k,l)
implicit none
integer :: k,l,int1,int2 = 11
data int1/11/
k = int1+3
l = int2+3
int1 = int1 - 3 !redefinition
int2 = int2 - 3 !redefinition
return
end subroutine

subroutine subb(k,l)
implicit none
integer k,l
k = -10
l = -15
return
end subroutine

If you still have an F77 compiler or you use F2C (use the -a option), you can use the following Fortran 77 program.

      program tst
      implicit none
      integer i1 ! not initialized
!
      call suba(i1)
      print 10,1,i1
      call subb(i1)
      print 10,2,i1
      call suba(i1)
      print 10,3,i1
   10 format('After call ',i1,' i1 = ',i4)
      end

      subroutine suba(k)
      implicit none
      integer k,int1
      data int1/11/
      k = int1+3
      int1 = int1 - 3
      return
      end

      subroutine subb(k)
      implicit none
      integer k
      k = -10
      return
      end

Fortran 77 standard, chapter 8.9: SAVE Statement. Cf. point (3) below.

 The execution of a RETURN statement or an END statement within a subprogram causes all entities
 within the subprogram to become undefined except for the following:

       (1) Entities specified by SAVE statements
       (2) Entities in blank common
       (3) Initially defined  entities  that  have  neither been redefined nor become undefined
       (4) Entities in a named common block that appears in the subprogram and appears in at least one 
            other  program  unit  that   is   referencing,   either  directly or indirectly, that subprogram

Thanks for that reference to the Fortran 77 standard, which I had not read carefully earlier. Now that you point it out, I can see the following curious comment about it in the Fortran 95 standard(!), under 1.5.2, “Fortran 77 Compatibility”.

If a named variable that was not in a common block was initialized in a DATA statement and did not have the SAVE attribute specified, FORTRAN 77 left its SAVE attribute processor dependent. The Fortran 95 Standard specifies (5.2.10) that this named variable has the SAVE attribute.

I don’t see where the Fortran 77 standard says that the SAVE attribute was processor dependent. In fact, in Fortran 77 SAVE was a statement/declaration, not an attribute. The word “attribute” did not show up when I searched for it in a PDF version of the Fortran 77 standard.

Do you know about any Fortran 77 compilers (or later compilers with -std=77 or some such option) that enforced the rule that you quoted?

There is one case where initializing a variable in a declaration is OK, but making it a PARAMETER is illegal: if it is of character type and subsequently read from, e.g. this program:

implicit none
character(3):: stuff = ‘Inf’
real inf
read(stuff,*) inf
print *,inf
end program

At one time the Oracle/Sun compiler would not automatically allocate all local variables on the stack. There was a compiler option -stackvar you had to envoke to get that behaviour. The SAVE attribute was still implied for a variable initialization without save. I don’t remember where it was saved though (stack or heap). I ran into this when I tried to recreate an old program from a listing in a report. I type it in verbatim and the only compiler that would compile and run without errors was the Oracle compiler. After a lot of head scratching I finally realized that original code was saving several variables during each subroutine call (ie it appeared to act as though a -static option was turned on by default). I had to “refactor” that behaviour out before the code would compile and run with Intel and gfortran. The original code was written in a time when variables were not put on the stack (usually) by default. I haven’t used the Oracle compiler in quite a while so I don’t know if this “feature” is still the default.

1 Like

(4) is also significant as it introduced the concept of scope for named common. This was “annoying”/unworkable as many “libraries” of routines, eg graphics or database management libraries used named common. This rule implied that their named common could go out of scope each time a (say) graphics routine was called.
A complying work around was to include all these named common in the main program, although this was not always practical, especially with 3rd party libraries.

I consider this a “poorly” thought out rule.
Fortunately, I do not know of any Fortran compiler that implemented this rule.

I have forgotten how overlay linkers managed this issue, but they did offer a way to remove common for different overlays. This did not depend on the F77 Section 8.9 clause.
The F77 standard was disappointing for what it included and also omitted, especially the functionality of ALLOCATE and the many processor dependant cop-outs.

You could also put the named common in SAVE declaration.