[comp.lang.fortran] What's the right way to get a block data from a library?

jonz@locus.com (Jon Ziegler) (03/16/91)

Sorry if this is a FAQ, but I don't usually read this group.

I'm curious what the current opinion is on the question of getting a
block data out of a library.  The hack blessed by ANSI in F77 was to
specify the block data name in an EXTERNAL statement.  Then the
unresolved external generated would cause the linker to do the right
thing.  There were several shortcomings in doing things this way:

	1. This STILL didn't do anything for unnamed block data.
	2. ANSI encouraged people to put all their function names
	   in EXTERNAL statements (B17), so that if hard unresolved
	   externals were really generated, there would be a whole
	   pile of them, leading to the situation described below.
	3. I said several, so I need at least three, but I can't
	   think of anything else right now.

As for 2., the natural progression, I suspect, is for people to put
everything in EXTERNAL statements in one include module, which they then
include in everything.  As this gets old and ugly, and included in
things where it really shouldn't be, all these hard externals cause all
sorts of really unrelated code to be pulled in.  This makes programs
unnecessarily large.

So people have looked for better solutions, and tried other things.  I
am told that on the RS/6000 they generate weak unresolved externals
for all named common blocks.  Thus a definition of a common block (which
can only be in a block data) will cause that block data to be brought
in.  This is nicely automatic, and no hard external is generated for
the EXTERNAL statement.  I see problems with this approach as well:

	1. A library with modules in it for several unrelated
	   programs can cause a program to get the wrong block
	   data.  A program will get the first block data to
	   define a common that it has.  It may get others too,
	   possibly causing conflicts, but maybe not.  This is
	   the same as when there are two functions in the lib-
	   rary with the same name, but does that make it okay?

	2. It's hard to do this in a compiler that you want to
	   be portable because you can't count on this ability
	   in the linker.

Anyway, my questions are:

	Am I completely wrong about this whole issue in some way?

	Has it been addressed in any new way by the F8x (or is it
	F9x?) people?

	Does anybody do the sorts of things I mentioned, like
	include modules with piles of EXTERNAL statements? or
	libraries with multiple, independent block datas?

	Could I solve the problem with the piles of EXTERNAL
	statements by adding a new unresolved external type
	that said "only resolve me if I'm a block data name?"
	Or are there other ways not involving the linker?

Rather a long post.  If you're still with me, thanks for listening and
thanks for any responses.  Please mail responses in addition to any posts,
as I'll only be looking for the next couple of weeks; FORTRAN ain't my
usual gig anymore.

Best regards,
Jon Ziegler
jonz@locus.com

maine@altair.dfrf.nasa.gov (Richard Maine) (03/18/91)

On 16 Mar 91 07:17:33 GMT, jonz@locus.com (Jon Ziegler) said:

     [... discussion of the problems of block data ...]

Jon> 	Has it been addressed in any new way by the F8x (or is it
Jon> 	F9x?) people?

Fortran 90 modules essentially replace most of the useful functionality
of Fortran 77 common blocks.  Although F90 still supports COMMON for
compatability with old codes (almost 100% of which use COMMON), you
don't really need it for most new codes.

As for the particular question of how block data relates to modules,
global variables in a module can be initialized within the module
itself.  Thus none of the problems of block data arise.

In my own F77 code, I avoid block data because of its portability
problems.  (This doesn't mean I do non-standard initialization of
COMMMON variables outside of block data - it just means I avoid
initialization of COMMON variables).  This does occasionally cause me
heartbreak when I'd really like to initialize something in COMMON, but
I resist the temptation and find another way.
--
--
Richard Maine
maine@altair.dfrf.nasa.gov

pa@appmag.com (Pierre Asselin) (03/19/91)

ANSI Fortran 77 declines  to  specify  "the  mechanism  by  which
programs  are  transformed  for use on a data processing system."
The interaction  between the compiler and loader is pretty much a
wildcard.

The block-data-in-a-library snag was discussed in this group before.
As I remember it,
  -most implementations will let you do it with some scheme or other;
  -no single method works on all implementations.

If I need portably initialized data, I keep  the  block  data  in
*source* form and INCLUDE it exactly once, outside of all program
units.  INCLUDE is not ANSI but,  as  discussed  earlier,  it  is
essentially portable.

  --Pierre Asselin, R&D, Applied Magnetics Corp.  I speak for me.
    3003jalp@ucsbuxa.ucsb.edu     --appmag.com doesn't work yet.