Reputation: 555
I am trying to compile some really old code (1986 and before). This code references an external function. Today's compilers ask for far more code to make this work. And I keep failing. I now created a small hello world program, which demonstrates the problem.
hello.for
PROGRAM hello
USE func
PRINT *, "Hello World!"
PRINT *, f ()
END PROGRAM hello
func.for
MODULE func
PUBLIC f
CONTAINS
FUNCTION f ()
f='Hello Func'
END FUNCTION
END MODULE
This has not only one, but two problems:
<type> FUNCTION <function>
or FUNCTION <function> () <type>::<something>
, but neither works.gfortran -c func.for
works (if I use the default return type real) and creates a mod file but linking does not work
$ gfortran hello.for
/tmp/ccHNzcXA.o: In function `MAIN__':
hello.for:(.text+0xa4): undefined reference to `__func_MOD_f'
collect2: error: ld returned 1 exit status
__func_MOD_f
is not contained in the mod file, but in the o file there is func.for__func_MOD_f
.
Any idea?
thanks
Upvotes: 2
Views: 11660
Reputation: 6915
You have two issues, the delcaration of f
and properly linking the module.
First, compiling the module yields the error:
% gfortran -c func.f
func.f:5:8:
f='Hello Func'
1
Error: Can't convert CHARACTER(1) to REAL(4) at (1)
This error is due to implicit typing of f
and an incompatible assignment. Fixing this is simple, declare f
explicitly as a character
instead of an implicit type. Add:
character(len=30) :: f
to the function and now your module compiles. Here is the modified module:
MODULE func
PUBLIC f
CONTAINS
FUNCTION f ()
character(len=30) :: f
f='Hello Func'
END FUNCTION
END MODULE
Your second problem is linking. Your command:
gfortran hello.for
fails because you did not specify the module object. If you already compiled the module you would specify:
gfortran hello.for func.o
if you were compiling them both at the same time you would do:
gfortran -o hworld func.for hello.for
if you are compiling everything individually:
gfortran -c func.for
gfortran -c hello.for
gfortran -o hworld hello.o func.o
Any of these will compile and run:
% ./hworld
Hello World!
Hello Func
If you are modernizing your code, it would also be worth adding implicit none
to avoid any implicit typing and declaring explicit variables for everything. e.g.:
module func
implicit none
contains
function f
implicit none
character(len=30) :: f
f='Hello Func'
end function f
end module func
and
program hello
use func
implicit none
print *, "Hello World!"
print *, f ()
end program hello
Upvotes: 3