Subject: Re: Fortran 77 name-mangling scheme
To: Patrick Welche <prlw1@newn.cam.ac.uk>
From: Jason Beegan <jtb@netbsd.org>
List: tech-userlevel
Date: 05/24/2001 21:13:14
> 
> autoconf's "checking for Fortran 77 name-mangling scheme" always fails. It
> seems it just tries to compile a fortran and C source file together like eg:
> 
> conftest.f:
>       subroutine foobar() 
>       return
>       end
> 
> conftest.c:
> char foobar();
> 
> int main ()
> {
>   foobar (); /* call the fortran subroutine */
> 
>   return 0;
> }
> 
> quartz% gcc -c -o cc_test.o conftest.c
> quartz% gcc -c -o cf77_test.o conftest.f
> quartz% nm -g cc_test.o
>          U foobar
> 00000000 T main
> quartz% nm -g cf77_test.o
> 00000000 T foobar_
> 
> 
> The above is on i386, elf. I take it this is meant to happen, but why?
> 
> Then leads to the obvious:
> quartz% gcc -o conftest -g -O2 cc_test.o cf77_test.o -lg2c -lm
> /usr/lib/libg2c.so: warning: tempnam() possibly used unsafely, use mkstemp()
> or mkdtemp()
> cc_test.o: In function `main':
> cc_test.o(.text+0x4): undefined reference to `foobar'
> /usr/lib/libg2c.so: undefined reference to `MAIN__'
> collect2: ld returned 1 exit status
> 
> 
> s/foobar/foobar_/g in the .c file just gets the MAIN__ error - any thoughts
> on that one?
> 
> Cheers,
> 
> Patrick
> 

MAIN__ is the Fortran equivalent of the C main() function.  Since
you're calling Fortran from C, MAIN__ doesn't get used, hence the
error in linking.

The workaround is to put a dummy MAIN__ function into your C program.
It can be practically any function, but I always use

       void
       MAIN__(void)
       {
	  abort();
       }

You can also use the -u option of the C compiler

    gcc -u MAIN__ -c -o cf77_test.o conftest.f

But the former is better (I think) because g77 doesn't have a -u
option so you can use the former regardless of whether you use g77 or
gcc for to do the linking.

If you look around pkgsrc/math you'll see a number of the packages
have these things already done for them.  (In fact all of them that
mix Fortran and C have).

By the way, g77 and f2c always mangle their symbols by converting the
names to lower case and appending an underscore.  So foobar_() is the
correct way to call the Fortran function foobar from C.


-- Jason Beegan