[comp.lang.fortran] Calling a C function from Fortran.

volovich@dendrite.Stanford.EDU (Gene Volovich) (08/03/90)

I'm calling a C function from a FORTRAN program on an RT running AOS, and 
using the standard C compiler and f77.  I actually got this to run, but 
my question is this: why does there need to be an underscore after the name
of the C function I'm calling?  Here's my code:

Fortran code:   ... 
                I=VISIT(J)
                ...

C code:         int visit_(k)
                int *k;
                {
                  printf("%d \n",*k);
                  return (*k+1);
                }

I compiled the FORTRAN code, and the C code, and then used f77 to link
them into an executable file.  I've never heard of anyone having this 
problem, so it all seems very strange to me.  Thanks, and I hope I'm
not wasting bandwidth with a trivial problem.  
 
                               +-------------------------------------------
- Gene Volovich                |  "We are the music makers.
Academic Information Resources |   We are the dreamers of dreams."
Stanford University            |                              - Willy Wonka
***************************************************************************

cik@l.cc.purdue.edu (Herman Rubin) (08/03/90)

In article <1990Aug2.191231.11783@portia.Stanford.EDU>, volovich@dendrite.Stanford.EDU (Gene Volovich) writes:
> I'm calling a C function from a FORTRAN program on an RT running AOS, and 
> using the standard C compiler and f77.  I actually got this to run, but 
> my question is this: why does there need to be an underscore after the name
> of the C function I'm calling?  Here's my code:

			[Code deleted]

I do not know when this was introduced, but unlike the older systems I have
used, in many a name is not a name.

In all the Unix systems I have seen, if a Fortran program uses xyz for a name
of a variable, function, subroutine, array, etc., it gets translated into 
_xyz_.  Similarly, the C name abc becomes _abc.  Thus if Fortran calls the
function pdq, the C function would have to be (in C) pdq_.   Also, Fortran
calls by reference, and C calls by value.  So if Fortran has the argument
x, it really passes the address of x, and C must use *x to get the value.
This is more understandable.
-- 
Herman Rubin, Dept. of Statistics, Purdue Univ., West Lafayette IN47907
Phone: (317)494-6054
hrubin@l.cc.purdue.edu (Internet, bitnet)	{purdue,pur-ee}!l.cc!cik(UUCP)

mwette@csi.JPL.NASA.GOV (Matt Wette) (08/03/90)

In article <2425@l.cc.purdue.edu>, cik@l.cc.purdue.edu (Herman Rubin) writes:
|> In article <1990Aug2.191231.11783@portia.Stanford.EDU>,
volovich@dendrite.Stanford.EDU (Gene Volovich) writes:
|> > I'm calling a C function from a FORTRAN program on an RT running AOS, and 
|> > using the standard C compiler and f77.  I actually got this to run, but 
|> > my question is this: why does there need to be an underscore after
the name
|> > of the C function I'm calling?  Here's my code:
|> 
|> 			[Code deleted]
|> 
|> I do not know when this was introduced, but unlike the older systems I have
|> used, in many a name is not a name.
|> 
|> In all the Unix systems I have seen, if a Fortran program uses xyz
for a name
|> of a variable, function, subroutine, array, etc., it gets translated into 
|> _xyz_.  Similarly, the C name abc becomes _abc.  Thus if Fortran calls the
|> function pdq, the C function would have to be (in C) pdq_.   Also, Fortran
|> calls by reference, and C calls by value.  So if Fortran has the argument
|> x, it really passes the address of x, and C must use *x to get the value.
|> This is more understandable.


I see this as a very nice feature in Unix for the following reason:
It allows you to use Fortran and C libraries with mixed Fortran and
C sources.   Once I wrote mixed Fortran and C on a VAX and rand into
many  problems because many routines in the Fortran and C libraries
had matching names.  YECH!

 _____________________________________________________________________
 Matthew R. Wette		| Jet Propulsion Laboratory, 198-326
 mwette@csi.jpl.nasa.gov        | 4800 Oak Grove Dr, Pasadena,CA 91109
 ---------------------------------------------------------------------

sjc@key.COM (Steve Correll) (08/04/90)

In article <1990Aug2.191231.11783@portia.Stanford.EDU>, volovich@dendrite.Stanford.EDU (Gene Volovich) writes:
> I'm calling a C function from a FORTRAN program on an RT running AOS, and 
> using the standard C compiler and f77.  I actually got this to run, but 
> my question is this: why does there need to be an underscore after the name
> of the C function I'm calling?  Here's my code:

The Fortran 77 standard permits a program to use an intrinsic even though
it contains a user-coded function with the same name:

	logical function sin()
	sin = .true.
	end
C	This subroutine calls the user-written logical function "sin"
	subroutine s()
	logical sin
	external sin
	print *, sin() .eqv. .true.
	end
C	This subroutine calls the trig intrinsic "sin" which already
C	exists in Unix libm under the name "sin"
	subroutine t()
	print *, sin(1.0)
	end

The Unix Fortran implementors were faced with two conflicting requirement:

  1. They wanted to be able to use existing libm routines like "sin", which
    were originally invented for use with C, to provide the trig intrinsics.
  2. They wanted to emit something close to "sin" to implement the user-coded
    function "sin".

They chose to solve this by appending "_" to all user-written routine names.

On many operating systems, the problem doesn't occur because the intrinsics
in the libraries have names containing $ or other unusual characters so as
not to conflict with user-written routines.

Actually, just to confuse things, the Unix Fortran library offers yet another
class of names. The intrinsics in libm take their arguments by value (which
usually enhances execution speed), but when you pass an intrinsic as an
actual argument, the compiler must supply a wrapper which takes its argument
by reference in the standard Fortran fashion. Unix implementations may vary
in this regard, but the SunOS implementation uses a _r_ prefix, e.g. _r_sin.

C	This subroutine passes the intrinsic "sin" as an argument.
	subroutine u()
	intrinsic sin
	call foo(sin)
	end
-- 
...{sun,pyramid}!pacbell!key!sjc 				Steve Correll