[comp.unix.wizards] How FORTRAN allocates addresses for COMMON blocks?

ALEWIS%UTCVM.BITNET@cunyvm.cuny.edu (Adam Lewis) (07/22/88)

     Our group here at CECA is attempting to port a large finite
elements program written in FORTRAN to a 68020 machine running
Sys V.   The particular compiler we're using is the from SVS.
The program that we are working on attempts to simulate
variable length arrays in FORTRAN by using overlapped COMMON
blocks and the fact that FORTRAN does not do array bounds range
checking.   The problem is that one needs to know exactly how your
COMMON blocks are allocated addresses in order to avoid overwriting
something that you shouldn't overwrite.  Maybe an example will help
make sense of this.  Suppose you have two COMMON blocks:

                 COMMON /A/ IA(1)
                 COMMON /B/ IAVAIL(99),LWRD

and assume that you know that the COMMON blocks are allocated storage
based upon lexographic order (this is the way that the FORTRAN
compiler under VMS allocates storage for COMMON blocks).  As long as
you take care not to place anything past the end of the /B/ COMMON
block, you can run subscripts for the array IA from 1 to 100.
    Does anybody out there have any idea how the different FORTRAN
compilers for UNIX assign addresses to COMMON blocks?   It would seem
to me that this kind of thing can differ greatly from compiler to
compiler.   We have not yet been able to determine just how our
compiler does this.  If anybody has some ideas, please drop a message
and I'll summarize the results to the net.
----------------------------------------------------------------------
Adam Lewis
Center of Excellence for Computer Applications
University of Tennessee, Chattanooga
Chattanooga, TN 37403-2598
(615)755-4388
I-net: ALEWIS@UTCVM.BITNET
----------------------------------------------------------------------

andrew@frip.gwd.tek.com (Andrew Klossner) (07/26/88)

[]

	"Does anybody out there have any idea how the different FORTRAN
	compilers for UNIX assign addresses to COMMON blocks?"

Unix compilers don't assign addresses to COMMON blocks.  The loader
does this.  It does not guarantee any particular order on those blocks,
and the programmer cannot depend on an order.

One way to force an order to common blocks is to create an assembly
file which establishes the contents of those blocks in a particular
order and exports them.  Your example:

	COMMON /A/ IA(1)
	COMMON /B/ IAVAIL(99),LWRD

might give rise to an ordering assembly file such as the following:

		.data
		.global _A_
	_A_:	.long	1		/* IA(1) */
		.global	_B_
	_B_:	.long	99		/* IAVAIL(99) */
		.long	1		/* LWRD */

(Your assembler pseudo-ops may vary.)

Needless to say, this sort of programming is fragile and hard to
maintain.  If you could reorganize your program not to depend on common
block ordering (perhaps by putting everything into one big common
block), you would be better off.

  -=- Andrew Klossner   (decvax!tektronix!tekecs!andrew)       [UUCP]
                        (andrew%tekecs.tek.com@relay.cs.net)   [ARPA]