Silverfrost Forums

Welcome to our forums

Save Attributes 2

8 Aug 2010 10:48 #6741

7.8.2010

Paul,

First of all, please delete the previous post on this subject. Although this seems to be a very minor “problem”, I have seen it many times. I have now managed to condense the problem to a small (dummy) program named Test: When I compile the program Test with the options /List and /Dump (see compall.txt), I find in the list Test.lis 7 Save attributes for local variables.

SAVE INTEGER(KIND=3) IFALLL(10)
SAVE INTEGER(KIND=3) M
SAVE INTEGER(KIND=3) MAX_I
SAVE INTEGER(KIND=3) MIN_I
SAVE REAL(KIND=1) DELTA_Z
SAVE REAL(KIND=1) X1
SAVE REAL(KIND=1) C3

I have used the latest FTN95 version 5.50 as you can see from the files *.lis.

Since there is nowhere any Save statement I wonder where the Save attributes come from. Is it just because the call of an internal subroutine is considered by FTN95 as a leave from the calling subroutine?

Best regards,

Klaus Lassmann

Compile.bat:

del comp.lis
del *.obj

ftn95  Test.f95  /Checkmate /Full_Debug /list /dump >> comp.lis

Test program

!     ###############
      Subroutine Test
!     ###############

        Implicit None

        Real             :: C3, x1, Delta_z

        Integer          :: Min_i, Max_i, m

        Integer , Dimension (10) :: ifalll
 
!       ------------------------------------------------------------------

        m      = 5
        ifalll = 1

        Min_i  = Minval ( ifalll (1:m ))
        Max_i  = Maxval ( ifalll (1:m ))

        C3     = 0.

        Call Test_01

        x1     = Delta_z

        Write (*,*) x1, C3, Min_i, Max_i

!     ########
      Contains
!     ########

        Subroutine Test_01

           Implicit    None
           Delta_z  = 2.

        End Subroutine Test_01
 
 
!     ###################
      End Subroutine Test
!     ###################
 

Test.lis Silverfrost FTN95/WIN32 Ver 5.50.0 Test.F95 Sun Aug 8 12:37:53 2010

Compiler Options in Effect:
    CHECKMATE COLOUR DELETE_OBJ_ON_ERROR DUMP FULL_DEBUG LIST MINIMISE_REBUILD  NO_QUIT 
    NON_STANDARD SINGLE_THREADED 

   0001                                                                                          AT 0
   0002   !     ###############                                                                  AT 0
   0003         Subroutine Test                                                                  AT 0
   0004   !     ###############                                                                  AT 3a
   0005                                                                                          AT 3a
   0006           Implicit None                                                                  AT 3a
   0007                                                                                          AT 3a
   0008           Real             :: C3, x1, Delta_z                                            AT 3a
   0009                                                                                          AT 3a
   0010           Integer          :: Min_i, Max_i, m                                            AT 3a
   0011                                                                                          AT 3a
   0012           Integer , Dimension (10) :: ifalll                                             AT 3a
   0013                                                                                          AT 3a
   0014   !       ------------------------------------------------------------------             AT 3a
   0015                                                                                          AT 3a
   0016           m      = 5                                                                     AT 3a
   0017           ifalll = 1                                                                     AT 45
   0018                                                                                          AT 6f
   0019           Min_i  = Minval ( ifalll (1:m ))                                               AT 6f
   0020           Max_i  = Maxval ( ifalll (1:m ))                                               AT b8
   0021                                                                                          AT 101
   0022           C3     = 0.                                                                    AT 101
   0023                                                                                          AT 10c
   0024           Call Test_01                                                                   AT 10c
   0025                                                                                          AT 11a
   0026           x1     = Delta_z                                                               AT 11a
   0027                                                                                          AT 12e
   0028           Write (*,*) x1, C3, Min_i, Max_i                                               AT 12e


  Dump of all variables in TEST

  Local Variables
SAVE            INTEGER(KIND=3)      IFALLL(10)          @ 0   (at line 15)
SAVE            INTEGER(KIND=3)      M                   @ 40  (at line 11)
SAVE            INTEGER(KIND=3)      MAX_I               @ 44  (at line 11)
SAVE            INTEGER(KIND=3)      MIN_I               @ 48  (at line 11)
SAVE            REAL(KIND=1)         DELTA_Z             @ 52  (at line 9)
SAVE            REAL(KIND=1)         X1                  @ 56  (at line 9)
SAVE            REAL(KIND=1)         C3                  @ 60  (at line 9)

  Total stack size: 40 bytes
  Total static size: 76 bytes


   0029                                                                                          AT 0
   0030   !     ########                                                                         AT 0
   0031         Contains                                                                         AT 0
   0032   !     ########                                                                         AT 0
   0033                                                                                          AT 0
   0034           Subroutine Test_01                                                             AT 0
   0035                                                                                          AT 1d
   0036              Implicit    None                                                            AT 1d
   0037              Delta_z  = 2.                                                               AT 1d


  Dump of all variables in TEST_01


  Total stack size: 16 bytes
  Total static size: 76 bytes


   0038                                                                                          AT 39
   0039           End Subroutine Test_01                                                         AT 39
   0040                                                                                          AT 39
   0041                                                                                          AT 39
   0042   !     ###################                                                              AT 39
   0043         End Subroutine Test                                                              AT 39
   0044   !     ###################                                                              AT 39
   0045                                                                                          AT 39




End of Compilation - Clocked 0.02 seconds
8 Aug 2010 10:50 #6742

Sorry, the file test.lis has been cut. Here it is:

Silverfrost FTN95/WIN32 Ver 5.50.0  Test.F95  Sun Aug  8 12:37:53 2010

Compiler Options in Effect:
    CHECKMATE COLOUR DELETE_OBJ_ON_ERROR DUMP FULL_DEBUG LIST MINIMISE_REBUILD  NO_QUIT 
    NON_STANDARD SINGLE_THREADED 

   0001                                                                                          AT 0
   0002   !     ###############                                                                  AT 0
   0003         Subroutine Test                                                                  AT 0
   0004   !     ###############                                                                  AT 3a
   0005                                                                                          AT 3a
   0006           Implicit None                                                                  AT 3a
   0007                                                                                          AT 3a
   0008           Real             :: C3, x1, Delta_z                                            AT 3a
   0009                                                                                          AT 3a
   0010           Integer          :: Min_i, Max_i, m                                            AT 3a
   0011                                                                                          AT 3a
   0012           Integer , Dimension (10) :: ifalll                                             AT 3a
   0013                                                                                          AT 3a
   0014   !       ------------------------------------------------------------------             AT 3a
   0015                                                                                          AT 3a
   0016           m      = 5                                                                     AT 3a
   0017           ifalll = 1                                                                     AT 45
   0018                                                                                          AT 6f
   0019           Min_i  = Minval ( ifalll (1:m ))                                               AT 6f
   0020           Max_i  = Maxval ( ifalll (1:m ))                                               AT b8
   0021                                                                                          AT 101
   0022           C3     = 0.                                                                    AT 101
   0023                                                                                          AT 10c
   0024           Call Test_01                                                                   AT 10c
   0025                                                                                          AT 11a
   0026           x1     = Delta_z                                                               AT 11a
   0027                                                                                          AT 12e
   0028           Write (*,*) x1, C3, Min_i, Max_i                                               AT 12e


  Dump of all variables in TEST

  Local Variables
SAVE            INTEGER(KIND=3)      IFALLL(10)          @ 0   (at line 15)
SAVE            INTEGER(KIND=3)      M                   @ 40  (at line 11)
SAVE            INTEGER(KIND=3)      MAX_I               @ 44  (at line 11)
SAVE            INTEGER(KIND=3)      MIN_I               @ 48  (at line 11)
SAVE            REAL(KIND=1)         DELTA_Z             @ 52  (at line 9)
SAVE            REAL(KIND=1)         X1                  @ 56  (at line 9)
SAVE            REAL(KIND=1)         C3                  @ 60  (at line 9)

  Total stack size: 40 bytes
  Total static size: 76 bytes


   0029                                                                                          AT 0
   0030   !     ########                                                                         AT 0
   0031         Contains                                                                         AT 0
   0032   !     ########                                                                         AT 0
   0033                                                                                          AT 0
   0034           Subroutine Test_01                                                             AT 0
   0035                                                                                          AT 1d
   0036              Implicit    None                                                            AT 1d
   0037              Delta_z  = 2.                                                               AT 1d


  Dump of all variables in TEST_01


  Total stack size: 16 bytes
  Total static size: 76 bytes


   0038                                                                                          AT 39
   0039           End Subroutine Test_01                                                         AT 39
   0040                                                                                          AT 39
   0041                                                                                          AT 39
   0042   !     ###################                                                              AT 39
   0043         End Subroutine Test                                                              AT 39
   0044   !     ###################                                                              AT 39
   0045                                                                                          AT 39




End of Compilation - Clocked 0.02 seconds
8 Aug 2010 10:53 #6743

Would it not be better to apply any cut of a contribution already in the preview. Here, I could see my full contribution.

9 Aug 2010 3:20 #6744

Klaus,

If you remove the CONTAINS code, then the SAVE attribute does not appear. As I have not used CONTAINS in this way I am not sure if SAVE should be implied. Where CONTAINS is used in a module definition, SAVE is implied.

John

9 Aug 2010 6:18 #6745

The Fortran Standard does not appear to say that module variables automatically have the SAVE attribute but these variables are required to persist in the same way as SAVEd variables.

The fact that FTN95 appears to have set this attribute internally is not unreasonable given that this behaviour is required.

In a main program, SAVE can be applied to a variable but is redundant (the Standard says this). In the same way FTN95 allows you to use SAVE for a module veriable but it is also redundant in this context.

9 Aug 2010 9:47 #6746

Ignore my comments above. For some reason I assumed that it was a MODULE. I will take a look at this and get back to you.

9 Aug 2010 3:04 #6747

The SAVE attribute is added by the compiler when a routine CONTAINS other routines. This appears to provide a mechanism for avoiding problems that could arise due possible side effects when the contained routine is called.

The attribute may only be needed or convenient in very special circumstances but my inclination is to leave well alone.

23 Aug 2010 4:31 #6817

Paul,

I am certainly not an expert, but this argumentation sounds strange to me. In my opinion it should not be necessary to set the save attribute for all internal variables because calling an internal subroutine from subroutine A does not mean to leave subroutine A.

Klaus

23 Aug 2010 5:39 #6818

I can log this as something to be investigated but are you sure that it is important?

For only a few variables, the fact that they are SAVEd is not a great problem. It just means the storage is fixed whilst the program runs.

24 Aug 2010 7:41 #6819

I cannot judge whether this item is important or not. However, from all what I have read about Fortran 90, especially concerning the more general rules and concepts, I had not expected such a behaviour.

You mentioned in one of your replies that this is a measure against very unlikely side-effects. But the contrary could also happen. If a programmer had forgotten in a subroutine containing an internal subroutine to give a local variable the necessary SAVE attribute, this program would run with FTN95. But would it also run with other compilers?

Please take my arguments as what they are: simple remarks. Since I know this particular property of FTN95, I can live very well with it.

Klaus

25 Aug 2010 3:55 #6825

My interpretation of the Fortran Standard is that you can not assume that the variable has the SAVE attribute, if not specified, but there is no requirement of the compiler that it must not be saved. That is an efficiency of the compiler for memory shareing. Again I might be wrong again on my recollection of the Standard ! By the way, is the Fortran 95 Standard still valid or is it superceded by a more recent version ?

John

25 Aug 2010 9:46 #6828

The current Fortran Standard is 2003. Fortran 95 is a subset of 2003 and so is still valid. FTN95 is supported as conforming to Fortran 95.

29 Aug 2010 7:12 #6854

Quoted from PaulLaidler The SAVE attribute is added by the compiler when a routine CONTAINS other routines. This appears to provide a mechanism for avoiding problems that could arise due possible side effects when the contained routine is called.

You can use SAVE if you want. I'm not sure it is needed in such cases though. The main reason to use CONTAINS is to provide functions which access variables in the parent scope; it would be a pity if these were made static.

What about ALLOCATED arrays! Are these made static?

PS. I think that variables in modules should be declared with SAVE explicitly if needed; a compiler can treat these as automatic variables.

3 Sep 2010 1:10 #6890

davidb wrote:

PS. I think that variables in modules should be declared with SAVE explicitly if needed; a compiler can treat these as automatic variables.

I don't think this is the case, as their scope should be all routines that use the module. This appears to be a similar argument that has been used for the scope of COMMON blocks. I don't know any compilers that do not effectively apply the SAVE attribute to variables in either COMMON or Modules. If this is not done, then it is very unfriendly of the compiler. Is this where your comment is going ? John

Please login to reply.