Memory management
 2-19  MEMORY MANAGEMENT
 ***********************
 (Thanks to Craig Burley for making subtle points clear) 
 Memory allocation problems create nasty bugs, of the kind that appear 
 and disappear without apparent reason, and may trash computations
 without causing error messages. 

 Size of memory representation for different data types
 ------------------------------------------------------
 The FORTRAN 77 standard (2.13) imposes few restrictions on the
 representation of variables in memory, it specifies only the relative
 sizes of some of the data types.
 The standard explicitly avoids comparing the size of characters and 
 non-character data and defines two unrelated measurement units, 
 character storage unit (CSU) and numeric storage unit (NSU).
 The sizes specified are:
      Data type          Size
      ----------------   -----
      INTEGER            1 NSU
      REAL               1 NSU
      LOGICAL            1 NSU
      DOUBLE PRECISION   2 NSU      (consecutive)
      COMPLEX            2 NSU      (consecutive)
      CHARACTER*n        1 CSU * n  (consecutive)
 Because the relative size of all the numeric data types is specified 
 in the standard, operations like EQUIVALENCE, associating different 
 sets of variables in CALL/SUBROUTINE pairs, and re-declarations of 
 COMMON blocks, will give standard results on numeric data.
 In other words, the standard ensures that aliasing operations 
 (provided character types are not present) will give standard 
 results without imposing impossible restrictions on the 
 implementation of storage.
 For example:
      INTEGER	int
      REAL		x
      EQUIVALENCE (int , x)
      
 That way you can read a REAL variable and manipulate it in 
 a portable way using the almost universal two's complement 
 representation of integers.
   
 Array types
 -----------
 Arrays are very important, and usually take up most of the memory 
 used by a program. No wonder different array types were developed
 and are implemented:
 Constant -     array dimensions are specified by constants that
                can be computed at compile-time.
 Adjustable -   are passed to a procedure; dimensions are passed 
                with other variables from the calling procedure.
 Assumed size - are passed to a procedure; upper-bound of last 
                dimension is unknown to the called procedure, 
                programmer is responsible for not getting out
                of array bounds.
 Automatic -    (Fortran 90) array dimensions are not compile-time
                constants, and may change on each invocation.
 Allocatable -  (Fortran 90) array dimensions may be determined
                at run-time.

 Where in the program memory is allocated? 
 -----------------------------------------

 Is memory always allocated top-down?
 ------------------------------------

 How much you can count on unSAVEd static memory?
 ------------------------------------------------
      PROGRAM AUTSAV
      CALL SUB(0)
      CALL SUB(1)
      END
      SUBROUTINE SUB(FLAG)
      INTEGER
     *			FLAG, ARRAY(100)
      IF (FLAG .EQ. 0) THEN
        ARRAY(100) = 123456789
      ELSE
        IF (ARRAY(100) .EQ. 123456789) THEN
          WRITE (*,*) ' AUTOSAVING PROBABLY IMPLEMENTED '
        ELSE
          WRITE (*,*) ' AUTOSAVING NOT SUPPORTED '
        ENDIF
      ENDIF
      RETURN
      END

 Call-by-reference vs. copying in/out
 ------------------------------------
 The proper way to check what argument-passing mechanism your compiler 
 uses, is to look in the assembly language listings it produces.
 Aho, Sethi and Ullman in the dinosaur book (p. 427) have a small 
 Pascal program that gives different results if the parameter-passing
 mechanism is call-by-reference or copy-restore (copy-in copy-out).
 A Fortran version of their program is non-standard (FORTRAN 77 standard,
 section 15.9.3.6, Restrictions on Association of Entities) discusses 
 exactly such programs and explicitly prohibit them, probably so that 
 both parameter-passing mechanisms would give the same result.
 Being non-standard the following program can't be guaranteed to work 
 properly (or at all), but anyway it's interesting.
 
      PROGRAM CPINOUT
      INTEGER	i
      COMMON	i
      i = 1
      CALL SUB(i)
      IF (i .EQ. 0) WRITE(*,*) ' Call-by-reference was used '
      IF (i .EQ. 2) WRITE(*,*) ' Copy-restore was used '
      END
      SUBROUTINE SUB(i)
      INTEGER	i, j
      COMMON	j
      i = 2
      j = 0
      RETURN
      END

 Another program explicitly prohibited by 15.9.3.6 is:

      PROGRAM CPINOUT
      INTEGER	i, j
      i = 1
      j = 1
      CALL SUB1(i,i)
      CALL SUB2(j,j)
      IF ((i .EQ. 0) .AND. (j .EQ. 2))
     *   WRITE(*,*) 'Call-by-reference was used '
      IF (i .EQ. j) WRITE(*,*) 'Copy-restore was used '
      END
      SUBROUTINE SUB1(i,j)
      INTEGER	i, j
      i = 2
      j = 0
      RETURN
      END
      SUBROUTINE SUB2(i,j)
      INTEGER	i, j
      j = 0
      i = 2
      RETURN
      END


Prev Contents Next