To port programs running on Tru64Unix to RH7.3 Linux with the default compiler:
GNU Fortran 0.5.26 20000731 (Red Hat Linux 7.3 2.96-110)in the standard default environment, the following changes are required. Most cases listed below are not detected at compiler level and give rise to strange error messages during execution.
options/extend_source is invalid and the continuation
flag is required for lines longer than 72 characters
RECL parameter of the OPEN statement is given
in bytes for every file type, both formatted and unformatted
<ret> is typed
$ cat t1.f
program t1
c
i1=3
i2=15
i3=15678910
d1=0.0049
c
write(6,'(1h ,3i10,f10.4)') i1,i2,i3,d1(1)
write(6,*) i1,i2,i3,d1(1)
c
call exit
$ .a.out
3 15 15678910 0.0049
3 15 15678910 0.00490000006
True64Unix reserves a predefined fixed size to free format variables,
usually 10 spaces. Linux leaves limited blank space (1 or 2 spaces) in
front of each variable. The different behaviour is emulated in the example.
INTEGER
iibits and
ibits to distinguish among different byte size of arguments, only
ibits is available; the same applies for every intrinsic function
lib_find_file, such variables must be
initialized to blank and their useful length must be computed using
str_trim
PARAMETER definitions, a
compile error is generated for definitions of the following type:
parameter (TOLOW=ichar('a')-ichar('A'))
parameter (PP=int(7.2))
In such cases use a variable instead of a parametric declaration
Tru64Unix scripts must be changed accordingly
_ (undescore). If the routine name includes one or
more underscores, it must be trimmed with two undescores __ as in
the following examples:
lib_skpc__(chr, line, ll) get_env__(var_name, var_val, len) vaxd_(vaxr, uixr)
integer vos(1:3),pl c pl=vos(1).and.vos(3)must be changed to:
integer vos(1:3),pl
logical la,lb,lc
integer ila,ilb,ilc
equivalence (la,ila),(lb,ilb),(lc,ilc)
c
ila=vos(1)
ilb=vos(3)
lc=la.and.lb
pl=ilc
implicit none)
do 900 while (istat.eq.0)
read(unit=55,fmt='(a)',iostat=istat) line
if(istat.ne.0) go to 900
EOF is reached when istat value is different from zero.
As the do while detects istat after the read
operation, depending on code problems may arise if the while loop executes
once more after file end.
Therefore it is a safe practice to insert a check on istat after the
read statement as shown in the code fragment.
integer bad_tank(111:578,5),off_tank(111:578,5)
real*8 init_calib(111:578,5)
c
call vzero(bad_tank,468*5)
call vzero(off_tank,468*5)
call vzero(init_calib,468*5)
the compiler prints a warning about different types. Use
equivalence to suppress warning
True64Unix are:
LBC = /cern/pro/lib
LB = /lvdusr/lvd/lib
.................
-lX11 -L$(LBC) -lgraflib -lgrafX11 -lkernlib -lpacklib \
-L$(LB) -llvdr
Libraries required by Linux are:
LBC = /cern/pro/lib
LB = /lvdusr/lvd/lib
.................
-L$(LBC) -lgraflib -lgrafX11 -lkernlib -lpacklib \
-L/usr/X11R6/lib -lX11 -lnsl -lcrypt -ldl \
-L$(LB) -llvdr
MAIN__ symbol is created in the object file. In such
cases the program cannot be linked and no executable is produced.
The error arises in one of the following cases:
subroutine or function statement is missing.
G77 compilers up to version 3.2 compile the code without error messages.
In this case Tru64Unix native compilers give rise to a fatal error with
the following message:
$ f77 -what
DIGITAL Fortran 77 Driver V5.2-10
DIGITAL Fortran 77 V5.2-171-428BH
$ f77 -c ffunc.f
fort: Error: ffunc.f, line 6: Statement not valid in this
program unit return
function statement declares a function without arguments
and without dummy parenthesys, i.e.
real*4 function gauss invalid code
MAIN module. The correct syntax is:
real*4 function gauss() correct syntax
implicit none statement gives
rise to the following compiler errors:
$ g77 -c ffunc.f
ffunc.f: In program `MAIN__':
ffunc.f:1:
real*4 function fcall
1
ffunc.f:3: (continued):
implicit none
2
Statement at (2) invalid in context established by statement at (1)
When one or more of the above errors are present in the code, the link phase fails with messages of the following type.
/home/hbo1/lvd/tmp/libtwins30806.a(twins30806.o): In function `MAIN__':
twins30806.o(.text+0x1b1e8): multiple definition of `MAIN__'
main_twins30806.o(.text+0x0): first defined here
/usr/bin/ld: Warning: size of symbol `MAIN__' changed from 2182 to 285 in
/home/hbo1/lvd/tmp/libtwins30806.a(twins30806.o)
/home/hbo1/lvd/tmp/liblvadam.a(lsr32.o): In function `MAIN__':
/home/hbo1/lvd/tmp/lsr32.f:503: multiple definition of `MAIN__'
main_twins30806.o(.text+0x0): first defined here
/usr/bin/ld: Warning: size of symbol `MAIN__' changed from 285 to 251 in
/home/hbo1/lvd/tmp/liblvadam.a(lsr32.o)
main_twins30806.o: In function `MAIN__':
main_twins30806.o(.text+0xa4): undefined reference to `lvsel_'
/home/hbo1/lvd/tmp/twins/tmp/liblvadam.a(lsr32.o): In function `lsr_smear__':
/home/hbo1/lvd/tmp/twins/tmp/lsr32.f:202: undefined reference to `lsr_gauss__'
/home/hbo1/lvd/tmp/twins/tmp/liblvadam.a(lsr32.o): In function `lsr_f0nfl__':
/home/hbo1/lvd/tmp/twins/tmp/lsr32.f:493: undefined reference to `lsr_gauss__'
collect2: ld returned 1 exit status
To detect the failing code, either make use of the unresolved references,
that in the example are related to modules lvsel_ (missing
subroutine statement) and lsr_gauss__ (missing () in
function statement) or use the nm utility that lists symbols
in object files, as shown in the examples.
nm may process any object compatible files, i.e.
file.o or file.a or executable or a.out if no file
argument is given. When running nm on a library or executable, use the
-print-file-name option.
$ nm allx.o | grep MAIN check in MAIN present
00000068 T MAIN__
$ nm --numeric-sort --extern-only allx.o list symbols by memory address
U do_lio
U e_wsle
U s_wsle
00000000 T lsrdata_
00000000 D lsrstuff_
00000008 T ftest_
000000b8 T MAIN__
00000118 T fcall_
MAIN in the code is found and the wrong
routine detected. In our example the wrong routine is placed between ftest and
fcall.