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.