[comp.lang.fortran] Is that a bug?

przemek@rrdstrad.nist.gov (Przemek Klosowski) (05/22/91)

Hello!

I turn to the collective wisdom of the net for advice whether I should
complain about this peculiar behavior of DEC Fortran and linker on
DECsystem 5810/Ultrix ver. 4.1. Let me add that the examples below
should compile under VMS and on IBM VM systems (I did not check these
particular files, but the program they were derived from did compile).
Following are two Fortran files containing a common block initialised by
DATA statements in both modules.

::::::::::::::                             ::::::::::::::                 
tst1.f                                     tst2.f                         
::::::::::::::                             ::::::::::::::                 
        common /aa/ aa1, aa2                       subroutine tst2        
        data aa1 /1.0/                             common /aa/ aa1, aa2   
        call tst2                                  data aa2 /2.0/         
        type *, aa1, aa2                           aa1=1.01               
        end                                        end                    

If these files are compiled separately, each of them seems to generate
a common block ACTUAL storage, because of its initialisation in each
module. This results in linker error:

% f77 -c tst1.f
% f77 -c tst2.f
% f77 tst1.o tst2.o
ld:
tst2.o: aa_: multiply defined
fort: Severe: Failed while trying to link.

Now when they are compiled together (allowing DEC fortran interprocedure
optimisations), everything is fine:

% f77 tst1.f tst2.f
% a.out
   1.010000       2.000000    

Is such usage of common block contradictory to some section of Fortran
77 standard? I understand that it is primarily linking problem, and
that it is hard to initialize common storage from two modules not
knowing about each other (think of what happens when the SAME variable
is initialised twice), but it seems to me that some systems can cope
with it. 

As I said, please send me e-mail, as I do not receive comp.lang.fortran on a
regular basis.
        
        Thank you for your help

                       przemek klosowski 

     _______________________________________________________________
    |  przemek@ndcvx.cc.nd.edu     |      przemek@rrdstrad.nist.gov |
    |  Physics Department         and     NIST, Reactor Bldg #235   |
    |  U. Notre Dame IN 46556      |      Gaithersburg MD 20899     |
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--
			przemek klosowski (przemek@ndcvx.cc.nd.edu)
			Physics Department
			University of Notre Dame IN 46556

jlg@cochiti.lanl.gov (Jim Giles) (05/23/91)

In article <PRZEMEK.91May22123736@rrdstrad.nist.gov> przemek@rrdstrad.nist.gov (Przemek Klosowski) writes:

|> [...]
|> ::::::::::::::                             ::::::::::::::                 
|> tst1.f                                     tst2.f                         
|> ::::::::::::::                             ::::::::::::::                 
|>         common /aa/ aa1, aa2                       subroutine tst2        
|>         data aa1 /1.0/                             common /aa/ aa1, aa2   
|>         call tst2                                  data aa2 /2.0/         
|>         type *, aa1, aa2                           aa1=1.01               
|>         end                                        end

The Fortran standard allows data loading of objects in a named common
block only within BLOCK DATA modules.  Blank common may not be data
loaded at all.  Most _quality_ implementations let you get away with 
it anyway.  Apparently, you've hit an implementation with no quality.
Most UNIX Fortran implementations are junk - but even most of those
allow data loading of common.

J. Giles

przemek@rrdstrad.nist.gov (Przemek Klosowski) (05/23/91)

Re: COMMON initialization by DATA statements

Hello!

Thank you for answering my question in comp.lang.fortran (copy of the
original article is enclosed at the end of the letter). It is clear
that the standard is walking a safe path and forbidding initialization
in multiple modules. Steve Correll (sjc@borland.com) writes:

   Section 9.2 of the ANSI X3.9-1978 Fortran 77 standard says you can't
   touch a named common block with a DATA statement unless you're inside
   a blockdata subprogram, and you can't touch a blank (unnamed) common
   block in a DATA statement anywhere. Section 16.2 says that if you
   touch a named common block in one blockdata subprogram, you can't touch
   it in any other blockdata subprogram. So your example is illegal in
   several respects.

It seems though that linkers often allow one to break this rule,
either by being very sophisticated (no example I know of) or by
looking the other way (VMS, allowing to initialize one variable
several times, and picking the "last" value without complaint). So in
this sense, Ultrix DEC Fortran together with Ultrix linker is "in the
middle of the road"---not sophisticated enough to resolve the problem,
not nonchalant enough to let it go, not stern enough to reject DATA
statements outside BLOCK DATA. I guess it would be B- for honesty and
trying. As usual, the guy in the middle of the road gets hit by the trucks 
going from both directions.

James Davies (jrbd@craycos.com) added a precious comment on the
dangers of using block data when one uses libraries:

  Using a block data causes a different problem if you link out of a
  library, since the block data won't get included (since it isn't
  "called" per se).  The usual solution is to declare the block data
  as EXTERNAL in some other routine (like the main program) that you
  are sure will get included.  This isn't guaranteed to work (the
  standard doesn't address link-time issues like this), but it works
  on VAX Fortran and many (but not all) Unix compilers.

In summary, all this mess makes me want to do run-time initialization.
For the case of the program at hand, I simply changed the compilation
rules for `make' so that both modules that initialize variables from the
common block will be compiled in the same invocation of f77 and the global
optimization will take care of the conflict.

PS. Thanks to all other respondents:
 Peter Mongomery (pmontgom@MATH.UCLA.EDU)
 John D. McCalpin (mccalpin@perelandra.cms.udel.edu)
 Jim Giles (jlg@woodsy.lanl.gov)

PSPS copy of the original posting

Newsgroups: comp.lang.fortran
Subject: Is that a bug? (please answer by e-mail)
--text follows this line--

Hello!

I turn to the collective wisdom of the net for advice whether I should
complain about this peculiar behavior of DEC Fortran and linker on
DECsystem 5810/Ultrix ver. 4.1. Let me add that the examples below
should compile under VMS and on IBM VM systems (I did not check these
particular files, but the program they were derived from did compile).
Following are two Fortran files containing a common block initialized by
DATA statements in both modules.

::::::::::::::                             ::::::::::::::                 
tst1.f					   tst2.f                         
::::::::::::::				   ::::::::::::::                 
        common /aa/ aa1, aa2		           subroutine tst2        
        data aa1 /1.0/			           common /aa/ aa1, aa2   
        call tst2			           data aa2 /2.0/         
        type *, aa1, aa2		           aa1=1.01               
        end				           end                    

If these files are compiled separately, each of them seems to generate
a common block ACTUAL storage, because of its initialization in each
module. This results in linker error:

% f77 -c tst1.f
% f77 -c tst2.f
% f77 tst1.o tst2.o
ld:
tst2.o: aa_: multiply defined
fort: Severe: Failed while trying to link.

Now when they are compiled together (allowing DEC fortran interprocedure
optimizations), everything is fine:

% f77 tst1.f tst2.f
% a.out
   1.010000       2.000000    

Is such usage of common block contradictory to some section of Fortran
77 standard? I understand that it is primarily linking problem, and
that it is hard to initialize common storage from two modules not
knowing about each other (think of what happens when the SAME variable
is initialised twice), but it seems to me that some systems can cope
with it. 

As I said, please send me e-mail, as I do not receive comp.lang.fortran on a
regular basis.
	

--
			przemek klosowski (przemek@ndcvx.cc.nd.edu)
			Physics Department
			University of Notre Dame IN 46556