[comp.lang.c] Calling Fortran from C

charlie@mica.stat.washington.edu (Charlie Geyer) (04/29/89)

In article <307@cbnewsh.ATT.COM> georg@cbnewsh.ATT.COM (georg.k.karawas) writes:

> The book 'Numerical Recipes in C' should contain a routine
> for matrix inversion. As it was already pointed in other
> articles, it is a hassle to work with pointers.
> A better solution might be to take a 'canned' FORTRAN routine
> from a standard package, like LINPACK, and call it from C.
> Be careful though that C stores arrays row-by-row.
> UNIX f77 compilers can produce object code which can be linked
> with a C calling program.

Yes this is the right answer and it applies even more so to algorithms more
complicated than matrix inversion for which reinventing the wheel would be
crazy.  I worry about portability though.  I hate to tell sombody I'm giving
software to "This is portable except the calls of FORTRAN from C and C from
FORTRAN; they work on our machines; you'll have to figure out how to make them
work on yours.  Here is a copy of message <14081@mimsy.UUCP> in comp.lang.c
by Chris Torek that tells how to do it on a VAX running BSD 4.x.  Have fun."

Is there anything in pANS C, Fortran 8x, and POSIX that will alleviate this
situation?  It's very annoying, especially these days when all of the really
high quality numerical stuff is still in FORTRAN and all of the good user
interface stuff is in C.

BVAUGHAN@pucc.Princeton.EDU (Barbara Vaughan) (04/29/89)

In article <1399@uw-entropy.ms.washington.edu>, charlie@mica.stat.washington.edu (Charlie Geyer) writes:

>
>In article <307@cbnewsh.ATT.COM> georg@cbnewsh.ATT.COM (georg.k.karawas) writes:
(many lines deleted)
>
>Is there anything in pANS C, Fortran 8x, and POSIX that will alleviate this
>situation?  It's very annoying, especially these days when all of the really
>high quality numerical stuff is still in FORTRAN and all of the good user
>interface stuff is in C.

This is especially true in my field, demography, where there is an
abundant literature of excellent Fortran programs, originally written
for mainframe computers (cards in, paper out).  I have found a way
to do high quality user interfaces in Fortran, using a Fortran-
callable library of programs called Spinlab. This is available for
Lahey F77L compilers, with plans for an MS Fortran version in the
future. (Maybe this exists already; I haven't checked lately.) This
library contains assembly language routines for screen addressing,
keyboard monitoring, scrolling, windows, everything needed to create
top quality user interfaces. I bought it from the author, but I think
Lahey is now licensed to sell it.

Barbara Vaughan

feg@clyde.ATT.COM (Forrest Gehrke) (05/01/89)

In article <1399@uw-entropy.ms.washington.edu>, charlie@mica.stat.washington.edu (Charlie Geyer) writes:
> 
> In article <307@cbnewsh.ATT.COM> georg@cbnewsh.ATT.COM (georg.k.karawas) writes:
> 
> > The book 'Numerical Recipes in C' should contain a routine
> > for matrix inversion. As it was already pointed in other
> > articles, it is a hassle to work with pointers.
> 
> Is there anything in pANS C, Fortran 8x, and POSIX that will alleviate this
> situation?  It's very annoying, especially these days when all of the really
> high quality numerical stuff is still in FORTRAN and all of the good user
> interface stuff is in C.

If portability and compatibility with ANSI C are foremost, then 
you probably would be best off with "Numerical Recipes in C"
(assuming you aren't interested in re-inventing).

If you go this route, the publisher sells a couple of diskettes
with the drivers and the C functions for everything listed
in the book (plus a number of general utilities used by
their routines).  (The information in the book about these
diskettes isn't exactly clear because they call 'em by
the same name--but there are TWO diskettes, one for about $30 
and the other $25).  The text itself is about $45.  They also
publish a smaller book which goes into more specific details
about their routines.

If numerical programming in C is your thing, I think this is
well worth the price.
   
--Forrest Gehrke

guy@auspex.auspex.com (Guy Harris) (05/02/89)

>Is there anything in pANS C, Fortran 8x, and POSIX that will alleviate this
>situation?

No, because:

	1) the proposed C 89 standard says little if anything about
	   FORTRAN (or is that "Fortran" now?);

	2) I suspect the Fortran 8x standard will say little if anything
	   about C;

	3) the C 89 standard and probably the Fortran 8x standard will
	   probably say very little indeed about calling sequences, or
	   other compiler-dependent and machine-dependent implementation
	   details;

	4) POSIX doesn't say anything about them either.

>It's very annoying, especially these days when all of the really
>high quality numerical stuff is still in FORTRAN and all of the good user
>interface stuff is in C.

This is a "quality of implementation" issue, and was left to the
marketplace; avoid the "there oughta be a law" syndrome.

cik@l.cc.purdue.edu (Herman Rubin) (05/02/89)

In article <1523@auspex.auspex.com>, guy@auspex.auspex.com (Guy Harris) writes:
> >Is there anything in pANS C, Fortran 8x, and POSIX that will alleviate this
> >situation?
> 
> No, because:
> 
> 	1) the proposed C 89 standard says little if anything about
> 	   FORTRAN (or is that "Fortran" now?);
> 
> 	2) I suspect the Fortran 8x standard will say little if anything
> 	   about C;
> 
> 	3) the C 89 standard and probably the Fortran 8x standard will
> 	   probably say very little indeed about calling sequences, or
> 	   other compiler-dependent and machine-dependent implementation
> 	   details;
> 
> 	4) POSIX doesn't say anything about them either.
> 
> >It's very annoying, especially these days when all of the really
> >high quality numerical stuff is still in FORTRAN and all of the good user
> >interface stuff is in C.
> 
> This is a "quality of implementation" issue, and was left to the
> marketplace; avoid the "there oughta be a law" syndrome.


There are two problems.  Each implementation of a language will have its
calling sequence.  This problem is unavoidable, and can be a major headache.
About the only thing that can be done about this is to

	a) have the various calling sequences in the #include files, or
	   otherwise, so that any language can call in any of the sequences,

	   and in addition,

	b) have system subroutines which can translate between calling
	   sequences.

This can even be a problem with ONE language.  Programs in Fortran
compiled with one calling sequence on the CDC 6x00 could not call programs
written in the other with arguments, and so there was a problem with the use
of library routines.  Neither was ever implemented, and the machines have
been phased out.



The bigger problem is names.  This seems to have started recently.  In the
systems I have used before UNIX, the statement

	SUBROUTINE ABC(X,Y,Z)

caused an object program with entry point ABC to be produced.  Now, a C
statement

abc(x,y,z)

would produce a program with entry point _abc on most implementations.  I
have seen the Fortran statement above produce one of

ABC, abc, _abc_, _ABC_,

and probably more occur.  These name alterations not only occur in the 
presentation of the name to the system, but in the names of all subroutines
called, blocks used, and global variables.  I have not seen an object code
editor which can modify the files so that this problem can be handled.
It should be considered essential that any user be able to access any
object program compiled by any processor by proper use of the calling
sequence and return, and this means knowing the system name of the program
and being able to instruct the compiler that a program with that name is
to be called.  A C program cannot now call abc, and a Fortran program
from a processor which prepends and postpends _ cannot call the C program
presented to C as pdq.
-- 
Herman Rubin, Dept. of Statistics, Purdue Univ., West Lafayette IN47907
Phone: (317)494-6054
hrubin@l.cc.purdue.edu (Internet, bitnet, UUCP)

chpf127@ut-emx.UUCP (John W. Eaton) (05/03/89)

feg@clyde.ATT.COM (Forrest Gehrke) writes:
> charlie@mica.stat.washington.edu (Charlie Geyer) writes:
>> 
>> ...  It's very annoying, especially these days when all of the really
>> high quality numerical stuff is still in FORTRAN and all of the good user
>> interface stuff is in C.
> 
> If portability and compatibility with ANSI C are foremost, then 
> you probably would be best off with "Numerical Recipes in C"

As has aleady been mentioned here, the Numerical Recipes in C code is
*not* portable [a bit of a problem with pointer arithmetic.  See
<13239@mimsy.UUCP> (26 Aug 88)]. 

> (assuming you aren't interested in re-inventing).

Well, re-inventing isn't even the real issue in many cases.  It's that
the algorithms given in Numerical Recipes (as the authors even admit)
are really just starting points and examples, not to be confused with
high quality numerical software (whatever *that* means :-).  Heck, the
Fortran (correct spelling? :-) routines don't even use dummy work work
vectors, but allocate some arbitrary amount of fixed storage for
scratch space.

Will there ever be a set of numerical routines in C which is as
complete, standard, available, well tested, inexpensive, etc.
as those currently available in Fortran?

> [ A plug for the Numerical Recipes in C diskettes deleted ...]
>    
> --Forrest Gehrke
-- 
John Eaton
chpf127@emx.cc.utexas.edu
Department of Chemical Engineering
The University of Texas at Austin
Austin, Texas  78712

guy@auspex.auspex.com (Guy Harris) (05/03/89)

>There are two problems.  Each implementation of a language will have its
>calling sequence.  This problem is unavoidable, and can be a major headache.

...

>The bigger problem is names.

No, there are at least three problems.  The third problem is the
representation of the language's data types, unless you consider that a
subclass of the first problem.  Passing a C character string to a
routine expecting a FORTRAN character string may not work, nor will
passing an integer value by reference, FORTRAN-style, to a routine
expecting it to be passed by value, C-style.

>It should be considered essential that any user be able to access any
>object program compiled by any processor by proper use of the calling
>sequence and return, and this means knowing the system name of the program
>and being able to instruct the compiler that a program with that name is
>to be called.

Well:

	1) that's not something within the purview of either the C or
	   FORTRAN standard, since it requires particular implementation
	   choices to be made for both languages; it falls between two
	   chairs, and touches on an area that standards committees
	   often try to avoid constraining, namely implementations. 
	   It's not within the purview of POSIX, either.

	2) given the "third problem", you may have to write a "jacket"
	   routine to translate data types, which means that it may not
	   necessarily be useful merely to patch up the name-space
	   problem, since you can't just call, say, the UNIX "open"
	   routine from FORTRAN in the same way you can call it from C.

I don't have Stu Feldman's paper on F77 handy, so I don't know if he put
in the prepended underscore, in part, to allow you to have a jacket for
the C routine "foobar" written in C and called "foobar_" from within C
and thus "foobar" from within FORTRAN, that does any requisite data type
translations.

cik@l.cc.purdue.edu (Herman Rubin) (05/04/89)

In article <1544@auspex.auspex.com>, guy@auspex.auspex.com (Guy Harris) writes:
> >There are two problems.  Each implementation of a language will have its
> >calling sequence.  This problem is unavoidable, and can be a major headache.
> 
> ...
> 
> >The bigger problem is names.
> 
> No, there are at least three problems.  The third problem is the
> representation of the language's data types, unless you consider that a
> subclass of the first problem.  Passing a C character string to a
> routine expecting a FORTRAN character string may not work, nor will
> passing an integer value by reference, FORTRAN-style, to a routine
> expecting it to be passed by value, C-style.

I see this as part of the calling sequence problem.  Certainly, for a 
Fortran program to call a C program which expects values rather than
references, the Fortran program must pass the parameters as it knows
how C expects to find them.  This might involve considerable work with
complicated data structures, but presumably these matters are problems
of the language and not of the implementation.

> >It should be considered essential that any user be able to access any
> >object program compiled by any processor by proper use of the calling
> >sequence and return, and this means knowing the system name of the program
> >and being able to instruct the compiler that a program with that name is
> >to be called.
> 
> Well:
> 
> 	1) that's not something within the purview of either the C or
> 	   FORTRAN standard, since it requires particular implementation
> 	   choices to be made for both languages; it falls between two
> 	   chairs, and touches on an area that standards committees
> 	   often try to avoid constraining, namely implementations. 
> 	   It's not within the purview of POSIX, either.

I have used several operating systems before UNIX.  On all of them, a name
was a name was a name.  The program cards and subroutine cards in Fortran
produced names in the object file identical to what appeared on the card.
Entry names and COMMON block names likewise.  Assembler-produced programs
did the same thing.  If I was going to use an Algol program it would still
be the same.  The calling sequence was a problem, even between Fortrans.
But not the names.

Speaking of names, why should one not be able to name a main program?

> 	2) given the "third problem", you may have to write a "jacket"
> 	   routine to translate data types, which means that it may not
> 	   necessarily be useful merely to patch up the name-space
> 	   problem, since you can't just call, say, the UNIX "open"
> 	   routine from FORTRAN in the same way you can call it from C.

There is no reason why the calling sequence for a subroutine to be called
from Fortran shoulc be the Fortran calling sequence.  But the Fortran 
compiler should, if necessary, have a patch to produce the necessary
calling sequence.

> I don't have Stu Feldman's paper on F77 handy, so I don't know if he put
> in the prepended underscore, in part, to allow you to have a jacket for
> the C routine "foobar" written in C and called "foobar_" from within C
> and thus "foobar" from within FORTRAN, that does any requisite data type
> translations.

This assumes that the writer of the C program writes it so it can be called
"foobar" from within Fortran on this particular type of system.  On our extinct
system, we did have a version of F77, but it did not use underlines at all.
Now suppose that we have an excellent program "foo" written in C, and the
object file is in the library.  Why should I not be able to use this program
from Fortran without recompiling it.  Or even if I have a full graphics
package of subroutines, why should this not be callable from any processor
regardless of its name?

A calling sequence requiring data editing is relatively easy.  On every
implementation I have used, I do know how to hack the .s program to change
the names, but can every user of a subroutine I provide be required to do so?
-- 
Herman Rubin, Dept. of Statistics, Purdue Univ., West Lafayette IN47907
Phone: (317)494-6054
hrubin@l.cc.purdue.edu (Internet, bitnet, UUCP)

tim@crackle.amd.com (Tim Olson) (05/04/89)

In article <1278@l.cc.purdue.edu> cik@l.cc.purdue.edu (Herman Rubin) writes:
| I have used several operating systems before UNIX.  On all of them, a name
| was a name was a name.  The program cards and subroutine cards in Fortran
| produced names in the object file identical to what appeared on the card.
| Entry names and COMMON block names likewise.  Assembler-produced programs
| did the same thing.  If I was going to use an Algol program it would still
| be the same.  The calling sequence was a problem, even between Fortrans.
| But not the names.

If an underscore is not prepended (or the names changed in some standard
unique way), then you run into the problem of potential name-space
conflicts with the assembly-level "helper" routines that almost always
exist.  These routines include "start" (the beginning of crt0, which
gets control and sets everything up for your program), help for non- or
undersupported intrinsics like unsigned modulo, short multiplies, etc.

If this were not done, then a user would just get mysterious
"multiply-defined" errors from the link of his program.


	-- Tim Olson
	Advanced Micro Devices
	(tim@amd.com)

gwyn@smoke.BRL.MIL (Doug Gwyn) (05/04/89)

In article <1278@l.cc.purdue.edu> cik@l.cc.purdue.edu (Herman Rubin) writes:
>I see this as part of the calling sequence problem.  Certainly, for a 
>Fortran program to call a C program which expects values rather than
>references, the Fortran program must pass the parameters as it knows
>how C expects to find them.  This might involve considerable work with
>complicated data structures, but presumably these matters are problems
>of the language and not of the implementation.

Woo, woo, let's also insist on a LISP compatible interface.

Let's also make C set up the run-time I/O support, activation contexts,
garbage collection, etc. needed by other languages just in case we use
them..

>I have used several operating systems before UNIX.  On all of them, a name
>was a name was a name.  The program cards and subroutine cards in Fortran
>produced names in the object file identical to what appeared on the card.
>Entry names and COMMON block names likewise.  Assembler-produced programs
>did the same thing.  If I was going to use an Algol program it would still
>be the same.  The calling sequence was a problem, even between Fortrans.
>But not the names.

I don't suppose you ever named any of your functions Q8Q...?

Name clashes among external identifiers has been a practical problem
ever since the invention of the link editor.

UNIX had several constraints that caused the external name mapping
conventions that it had.  One of them was a pre-existing assembler
that had no way to prevent names such as "r0" the register from being
confused with "r0" the external datum.  This caused the C compiler to
give external identifiers an unmistakable form.  When preexisting
assembly code was not an issue, as with the 3B series, the opposite
approach of giving registers etc. unique name formats such as "%0"
was followed and external identifiers were left alone.

C and Fortran external identifiers could not be mixed (such as in
implementing Fortran run-time support in C), due to differences in
behavior expected for the same names.  For example, SUBROUTINE FOPEN.

>Speaking of names, why should one not be able to name a main program?

Why add unnecessary complexity?

guy@auspex.auspex.com (Guy Harris) (05/04/89)

>I see this as part of the calling sequence problem.  Certainly, for a 
>Fortran program to call a C program which expects values rather than
>references, the Fortran program must pass the parameters as it knows
>how C expects to find them.  This might involve considerable work with
>complicated data structures,

Uhh, this tends to involve extensions to the language, as in VMS C's
"%VAL", etc. (or whatever the syntax is).  If you have a C routine that
expects an integral value, and you want to call it from a Fortran
routine, "considerable work with complicated data structures" ain't
going to cut it.

>but presumably these matters are problems of the language and not of
>the implementation.

The "value vs. reference" is a problem of the language. However, the
"Fortran character strings vs. C character strings" problem, which is a
*separate* part of this problem (it has nothing to do with value vs.
reference), is a matter of the implementation - C strings'
implementation tends to be constrained by the language definition
(although there could conceivably be surprises, if the implementor works
hard enough :-)), but Fortran strings' implementation aren't necessarily
so constrained.

For example, a quick check of the 4.3BSD F77 libraries indicate that its
"f77" (and, I suspect, most other UNIX "f77" implementations, since many
of them are derived from Feldman's) passes a Fortran string type by
passing a pointer to a character array (well, to its first element)
followed by an integral string length.  Said character arrays can be
blank-padded at the end (I think this may be
language-definition-related).

This is *not* what a typical C routine expects to see as a string.  I
don't know that there is a way in "standard Fortran" to pass a string in
a way that a naive C routine would find acceptable, and that will work
on all Fortran and C implementations (if somebody thinks there is, they
should exhibit it in detail, otherwise I'm not inclined to believe
them).  You could add an extension to Fortran to pass "C-style strings",
but not all Fortrans will necessarily support this; you'd have to get it
added to the language.

However, once you've done that, you now have questions like "how do I
pass a standard I/O stream pointer to a C routine that expects it?" 
Standard Fortran doesn't have structures, much less an "address of"
operator, so passing a standard I/O stream pointer - defined in most
UNIX standard I/O implementations, at least, as a pointer to a
particular type of data structure - is a bit hard....

Given the problems listed here, the "best approach" is probably to have
the C routines you call from Fortran be set up to have
"Fortran-generatable" calling sequences; this may mean you have to have
"jacket" routines for popular C routines with non-Fortran-generatable
calling sequences.  This may mean, though, that the "jacket" routine may
depend on the particular calling conventions of the Fortran you're
using; for instance, consider a Fortran that passes strings by passing
a pointer to the characters and the length vs. a Fortran that passes
them by passing a pointer to a block of memory containing the length
followed by the characters.

Of course, moving back to the structure problem, even if your Fortran
*does* support structures (I think VMS C and other ones have that as an
extension), there's no guarantee from the language specs that they'll
lay out data structures in the same way....

In short, your presumption is incorrect; it *is* an implementation problem.

>Speaking of names, why should one not be able to name a main program?

If one is speaking of names in C, why should one want to "name a main
program"?  What could you do given that facility that you can't do
without it?

cik@l.cc.purdue.edu (Herman Rubin) (05/04/89)

In article <10201@smoke.BRL.MIL>, gwyn@smoke.BRL.MIL (Doug Gwyn) writes:
> In article <1278@l.cc.purdue.edu> cik@l.cc.purdue.edu (Herman Rubin) writes:

			.........................

> Woo, woo, let's also insist on a LISP compatible interface.

Why not?  why should Fortran or C not be able to call a compiled LISP program?

> Let's also make C set up the run-time I/O support, activation contexts,
> garbage collection, etc. needed by other languages just in case we use
> them..

Each program better have its own I/O interface, etc.  There is a point in
having system ones with certain properties, but these are in the nature of
additional subroutines callable by the various processors.  I have had to
treat a Fortran-created file in C because the Fortran where the file was
being read did not have the Z format.

> >I have used several operating systems before UNIX.  On all of them, a name
> >was a name was a name.  The program cards and subroutine cards in Fortran
> >produced names in the object file identical to what appeared on the card.
> >Entry names and COMMON block names likewise.  Assembler-produced programs
> >did the same thing.  If I was going to use an Algol program it would still
> >be the same.  The calling sequence was a problem, even between Fortrans.
> >But not the names.
> 
> I don't suppose you ever named any of your functions Q8Q...?

Every system has its reserved words, including UNIX.  Every compiler 
likewise.

> Name clashes among external identifiers has been a practical problem
> ever since the invention of the link editor.

Agreed.  And they will continue to be.  Suppose several sources provide
routines designed to do the same thing.  You would need an object file
editor to handle the problem.  It should be provided.  But why should
Fortran, C, etc., have to have identical subroutines with different names
because of the namespace clash.

> UNIX had several constraints that caused the external name mapping
> conventions that it had.  One of them was a pre-existing assembler
> that had no way to prevent names such as "r0" the register from being
> confused with "r0" the external datum.

So rewrite the assembler so that the register r0 would be called !0 or
something similar.  Suppose there is reason to call a program sp?  The
register conventions would not allow this.  There are enough currently
illegal notations that one of them could be used for registers, where 
the problem is, rather than having everyone else do it.

>	  This caused the C compiler to
> give external identifiers an unmistakable form.  When preexisting
> assembly code was not an issue, as with the 3B series, the opposite
> approach of giving registers etc. unique name formats such as "%0"
> was followed and external identifiers were left alone.

This approach should have been followed everywhere.  Such changes to
assemblers are easy.  Even patches are easy, if a binary program 
editor is supplied.

> C and Fortran external identifiers could not be mixed (such as in
> implementing Fortran run-time support in C), due to differences in
> behavior expected for the same names.  For example, SUBROUTINE FOPEN.

So two functions with the same name should not appear in different
libraries?

> >Speaking of names, why should one not be able to name a main program?
> 
> Why add unnecessary complexity?

Because there can be reasons to refer to programs and entry points by
name when desirable.  Because people have used one program to operate
on another.  Because there are times when the same load process needs
to load more than one program which can be a "main" program.
-- 
Herman Rubin, Dept. of Statistics, Purdue Univ., West Lafayette IN47907
Phone: (317)494-6054
hrubin@l.cc.purdue.edu (Internet, bitnet, UUCP)

karl@haddock.ima.isc.com (Karl Heuer) (05/05/89)

In article <25509@amdcad.AMD.COM> tim@amd.com (Tim Olson) writes:
>If an underscore is not prepended ... you run into the problem of potential
>name-space conflicts with the assembly-level "helper" routines [e.g. "start"]

Actually, collision with register names and/or assembler instructions is the
stronger reason.  On machines where this isn't a problem, the helper routines
are typically written using the assembler's larger namespace, e.g. ".start".

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint

charlie@mica.stat.washington.edu (Charlie Geyer) (05/06/89)

Most of the discussion about this has gotten very far away from what I
see as the real problem (perhaps mistakenly).  A lot of comments have
been to the effect that there's no portable way to make it so that
*any* Fortran, C, or Lisp (!) program can be called from any other.

I just want an answer to a much simpler problem.  How to write an
intellegent C program (no strings or structures in arguments, no call
by value, etc.) that calls a Fortran subroutine or is called by one.
I know there is no portable answer to this now.  But shouldn't there
be?

This is often essential if one is to avoid reinventing the wheel at
the cost of years of work.

chris@mimsy.UUCP (Chris Torek) (05/06/89)

In article <1415@uw-entropy.ms.washington.edu>
charlie@mica.stat.washington.edu (Charlie Geyer) writes:
>I just want an answer to a much simpler problem.  How to write an
>intellegent C program (no strings or structures in arguments, no call
>by value, etc.) that calls a Fortran subroutine or is called by one.
>I know there is no portable answer to this now.  But shouldn't there
>be?

Perhaps there should.  But note that a Fortran compiler might use an
entirely different run-time environment (e.g., perhaps no stack at all)
than a C compiler, even on the same machine.

It is clear that no one language standard can constrain any *other*
language, and that therefore no one standard (for Fortran, C, PL/I,
APL, Lisp, DDL, rog-o-matic, or whatever) can require inter-language
calls.  It requires an inter-language standard to do this.

Good luck on getting together an inter-language standard ... you will
certainly need it.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

amanda@iesd.dk (Per Abrahamsen) (05/06/89)

In article <1415@uw-entropy.ms.washington.edu> charlie@mica.stat.washington.edu (Charlie Geyer) writes:

   ... How to write an intellegent C program [...] that calls a
   Fortran subroutine or is called by one. I know there is no portable
   answer to this now.  But shouldn't there be?

Something like

	extern "<language>" subrutine();

where <language> is any supported language?

C++ offer you that...

--
Per Abrahamsen,  amanda@iesd.dk, {...}!mcvax!diku!iesd!amanda

cik@l.cc.purdue.edu (Herman Rubin) (05/06/89)

In article <17333@mimsy.UUCP>, chris@mimsy.UUCP (Chris Torek) writes:
> In article <1415@uw-entropy.ms.washington.edu>
> charlie@mica.stat.washington.edu (Charlie Geyer) writes:
> >I just want an answer to a much simpler problem.  How to write an
> >intellegent C program (no strings or structures in arguments, no call
> >by value, etc.) that calls a Fortran subroutine or is called by one.
> >I know there is no portable answer to this now.  But shouldn't there
> >be?
> 
> Perhaps there should.  But note that a Fortran compiler might use an
> entirely different run-time environment (e.g., perhaps no stack at all)
> than a C compiler, even on the same machine.
> 
> It is clear that no one language standard can constrain any *other*
> language, and that therefore no one standard (for Fortran, C, PL/I,
> APL, Lisp, DDL, rog-o-matic, or whatever) can require inter-language
> calls.  It requires an inter-language standard to do this.
> 
> Good luck on getting together an inter-language standard ... you will
> certainly need it.

Even with the same language, different compilers can have different
calling sequences.  This problem can be handled by the process of 
having each compiler have access to the calling sequences of the others.

The harder problem is names.  Suppose I am writing a buffer refill program.
I could write this in Fortran or C (I would prefer C, but it would make
little difference).  On vector machines, I could vectorize it (maybe).
It is easy to call.  How do I name it?  If I give it a name in one
language, how will it appear to the system?  Can I call it at all?

I know how to produce a .s file as an intermediate and edit that file to
change the name.  But what do you do if source is not provided?  An object
file editor should be available to do the job, but I believe is not.

And the problem is greater if it is in a package.  There are statistics
packages with many formats.  What if it is necessary for someone like
Charlie to use several packages to do what he wants?  This is an important
question, and one which has been ignored by the computing and language
people.

The answer is not to make a universal calling sequence, as that prevents
development.  But there is no reason why names should be altered by 
processors, as is now the case.  And the calling sequences for the
processors should be public knowledge.
-- 
Herman Rubin, Dept. of Statistics, Purdue Univ., West Lafayette IN47907
Phone: (317)494-6054
hrubin@l.cc.purdue.edu (Internet, bitnet, UUCP)

mat@mole-end.UUCP (Mark A Terribile) (05/07/89)

In article <1415@uw-entropy.ms.washington.edu>, charlie@mica.stat.washington.edu (Charlie Geyer) writes:
> ...  How to write an intellegent C program (no strings or structures in
> arguments, no call by value, etc.) that calls a Fortran subroutine or is
> called by one.  I know there is no portable answer to this now.  But
> shouldn't there be?
 
> This is often essential if one is to avoid reinventing the wheel at
> the cost of years of work.

Well ... there is provision in C++ 2.0 for this.  Exactly what languages will
be supported (usually just C) is up to the implementation, but if you feel the
need to write compilers that provide the capability, there is a well-thought-
out syntax for the job.
-- 

(This man's opinions are his own.)
From mole-end				Mark Terribile

diamond@diamond.csl.sony.junet (Norman Diamond) (05/08/89)

In article <17333@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes:

>It is clear that no one language standard can constrain any *other*
>language, and that therefore no one standard (for Fortran, C, PL/I,
>APL, Lisp, DDL, rog-o-matic, or whatever) can require inter-language
>calls.  It requires an inter-language standard to do this.

True

>Good luck on getting together an inter-language standard ... you will
>certainly need it.

When DEC did exactly this, around 10 years ago, luck did not seem to be
part of it.  Of course, they had trouble integrating C with the rest of
it, because other languages only specified WHAT gets done by various
language constructs, but K&R added HOW it must be done for their
language.  (This must be the ultimate worst mistake that K&R made in
their specification of the C language.)  However, some wheels do not
really require re-invention, nor do they require luck if you want to
read about the existing invention before doing yours.

Seems a lot of people hate DEC because DEC learned their lessons before
everyone else did....

--
Norman Diamond, Sony Computer Science Lab (diamond%csl.sony.co.jp@relay.cs.net)
  The above opinions are my own.   |  Why are programmers criticized for
  If they're also your opinions,   |  re-inventing the wheel, when car
  you're infringing my copyright.  |  manufacturers are praised for it?

gwyn@smoke.BRL.MIL (Doug Gwyn) (05/09/89)

In article <10228@socslgw.csl.sony.JUNET> diamond@csl.sony.junet (Norman Diamond) writes:
>When DEC did exactly this, around 10 years ago, luck did not seem to be
>part of it.

DEC tried to do it, but I wouldn't call their attempt fully successful.

>... other languages only specified WHAT gets done by various language
>constructs, but K&R added HOW it must be done for their language.

I don't know what you mean by this.  Do you?

weyrich@csun1.UUCP (Orville Weyrich) (05/09/89)

From article <17333@mimsy.UUCP>, by chris@mimsy.UUCP (Chris Torek):
> It is clear that no one language standard can constrain any *other*
> language, and that therefore no one standard (for Fortran, C, PL/I,
> APL, Lisp, DDL, rog-o-matic, or whatever) can require inter-language
> calls.  It requires an inter-language standard to do this.
> 
> Good luck on getting together an inter-language standard ... you will
> certainly need it.

This has been a topic near and dear to me for a long time: We really should
have some kind of standard for inter-language communication.

Such a standard should be an add-on option to the existing language
standards, and should specify PORTABLE ways of specifying how to call
procedures/functions in other languages.  

If such a standard existed, then vendors would be able to claim that
their language X and language Y compilers met the interface standard, and
procurement personnel would be able specify such compatibility as a
requirement.

It is of course unreasonable to expect to be able to mix-n-match any
arbitrary compilers from arbitrary suppliers.

It is also unreasonable to expect to be able to pass anything between
languages transparently.  For example, if FORTRAN arrays of character
can contain null values, it is unreasonable to expect to be able to
pass such arrays to C, which treats nulls as "end of string". It would,
however, be reasonable to define a standard structure in C which could
be used to communicate string data with FORTRAN routines.

Anyone interested in trying to draft such a standard (which might
include proposed 'tweeks' to the language standards being mingled)?
My own interest would be mainly between FORTRAN and Ada, but I am sure
that there is also interest in linking FORTRAN with C and C with Ada.

E-mail me if you are interested.

Orville R. Weyrich, Jr.      weyrich@csun1.cs.uga.edu


-- 
Orville R. Weyrich, Jr.          | UUCP    : ...gatech!csun1!weyrich
Department of Computer Science   | INTERNET: weyrich@csun1.cs.uga.edu
University of Georgia            |
Athens, GA 30602 USA             | MA BELL : (404) 542-1082

joe@modcomp.UUCP (05/09/89)

Tim Olson writes:
>If an underscore is not prepended ... you run into the problem of potential
>name-space conflicts with the assembly-level "helper" routines [e.g. "start"]

Of course, the conflicts can be avoided by (manually) appending the
underscore to all the helper routines, rather than (automatically) to
the user routines.  At least, that's the way it works on our moto boxes,
and I've had no problem with it....

joe korty
uunet!modcomp!joe

diamond@diamond.csl.sony.junet (Norman Diamond) (05/10/89)

In article <10228@socslgw.csl.sony.JUNET> I wrote:
>>When DEC did exactly this, around 10 years ago, luck did not seem to be
>>part of it.

In article <10237@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes:

>DEC tried to do it, but I wouldn't call their attempt fully successful.

It would still be silly if someone who wants to reinvent this wheel
doesn't bother to look at what DEC did.

>>... other languages only specified WHAT gets done by various language
>>constructs, but K&R added HOW it must be done for their language.

>I don't know what you mean by this.  Do you?

Yeah, I think so.  Strings, for example.  Cobol, PL/I, Algol,
Fortran-77, Snobol, etc., have string types and say what kind of
operations can be done on strings.  C says that a string is terminated
with a '\0' byte.  Instead of assigning a null string to a target,
C programmers assign a '\0' byte, so the implementation of C library
routines can never be speeded up.  For other languages, improvements
are often made to implementations.

--
Norman Diamond, Sony Computer Science Lab (diamond%csl.sony.co.jp@relay.cs.net)
  The above opinions are my own.   |  Why are programmers criticized for
  If they're also your opinions,   |  re-inventing the wheel, when car
  you're infringing my copyright.  |  manufacturers are praised for it?

flint@gistdev.UUCP (05/11/89)

Dealing with blank-filled vs null terminated strings, calling conventions,
variable sizes, routine names, etc.  are all a pain.  The biggest pain is
when the system libraries are improperly constructed though. 

An example: The main() routine is in C which calls Fortran routines which
in turn call C routines.  Unfortunately, the Fortran parts use some string
functions that don't exist in the C library, so if you want it to work, you
have to link in the Fortran library.  Can you just add a -lF77?  Wrong,
that gives you a "duplicate function main()" error.  Ok, so you ar the
routines you need out of the Fortran library and link them in explicitly,
and you can make it link and work.  Now you want to put some debug output
into the Fortran codes and guess what: the routines needed aren't
available, and if you try to ar only the .o files out of libF77.a you need,
you eventually end up needing something that is in the same .o file as the
main() routine of libF77. 

The end result is that if I want to do any output at all from the Fortran
code, I have to call a C routine to do it.  All this pain could be avoided
if the genius who created the libF77.a had put the main() routine in it's
own .o all by itself, so that I could just copy the library and remove
main.o and link it.  But if you toss several routines into the same .o
together, then you can't take the extra main() out without taking out
something else that you have to have to do Fortran style I/O. 

Flint Pellett, Global Information Systems Technology, Inc.
1800 Woodfield Drive, Savoy, IL 61874 (217) 352-1165
INTERNET: flint%gistdev@uxc.cso.uiuc.edu
UUCP: {uunet,pur-ee,convex}!uiucuxc!gistdev!flint

ka@june.cs.washington.edu (Kenneth Almquist) (05/12/89)

The problem of differing calling conventions could be solved with a
stub generator.  Say you had a FORTRAN subroutine that you wanted to
call from C.  The input to the stub generator would include the name
of the FORTRAN routine, the types of its arguments, the name that the
routine was to be know from in C, and the types of the arguments to
be passed from C.  The output of the stub generator would be a C
callable routine which would convert the arguments to the appropriate
types for C (if necessary), run the FORTRAN routine, and finally
convert the resulting values back to the appropriate types for C
(again only if necessary).

The advantages of this approach are:

1)  The language standards don't have to change.  Instead, all that
is required is to develop a new standard for the stub specification
language.  So there is no need to convince the existing standards
committees to address the interlanguage communication problem.  They
haven't addressed it in the past, and there is no reason to expect
this to change in the near future.

2)  Another advantage is that existing compilers probably don't have
to change (see below).  If you own a C compiler and a FORTRAN compiler
for an IBM/PC compatible, the chances that the same company will have
written both compilers is relatively small.  Either of these companies
may have decided that being compatible with their competitor's compilers
is not worth the trouble.  On the other hand, a third party might be
willing to sell a stub generator that was compatible with both.

3)  The number of people who are interested in interlanguage communi-
cation is probably fairly small, and compiler writers might be hesitant
to add features that they think will be only used by a few of their
customers.  On the other hand, stub generators are relatively easy to
write, so a company might be willing to market a stub generator to a
much smaller market than a compiler company would target.  Alternatively,
users could write their own.

This does not address the issue of compatible run time systems.  Both
FORTRAN and C have relatively simple run time systems, so incompatibility
is not likely to be a major problem in this case.  The standard would
have to give standard names to the initialization and cleanup entry
points for the run time systems, so that a program with a C main routine
could initialize the FORTRAN run time system, and vice versa.
				Kenneth Almquist

tps@chem.ucsd.edu (Tom Stockfisch) (05/17/89)

In article <8197@june.cs.washington.edu> ka@june.cs.washington.edu (Kenneth Almquist) writes:
_The problem of differing calling conventions could be solved with a
_stub generator....
_ The standard would
_have to give standard names to the initialization and cleanup entry
_points for the run time systems, so that a program with a C main routine
_could initialize the FORTRAN run time system, and vice versa.
_				Kenneth Almquist


In calling fortran from C I would like to avoid the fortran library as
much as possible.  On our system the fortran i/o junk is almost 100k,
stripped.  I tend to use fortran just for LINPACK and other stuff that
does no i/o, so I hate the waste.
-- 

|| Tom Stockfisch, UCSD Chemistry	tps@chem.ucsd.edu

flaps@dgp.toronto.edu (Alan J Rosenthal) (05/18/89)

In article <7800008@gistdev> flint@gistdev.UUCP writes:
>An example: The main() routine is in C which calls Fortran routines which
>in turn call C routines.  Unfortunately, the Fortran parts use some string
>functions ...
>Can you just add a -lF77?  Wrong, ...
>
>The end result is that if I want to do any output at all from the Fortran
>code, I have to call a C routine to do it...

Why not just have your main in Fortran?  It could be just a call to cmain().
I think this solves this problem.  Of course, it doesn't solve this problem
when you are trying to compile with two non-C languages, but for just one it's
fine.

ajr

heilpern@ibd.BRL.MIL (Mark A. Heilpern ) (06/03/89)

In article <8905181540.AA06912@cartier.dgp.toronto.edu> flaps@dgp.toronto.edu (Alan J Rosenthal) writes:
[lots deleted]
>Why not just have your main in Fortran?  It could be just a call to cmain().
>I think this solves this problem.  Of course, it doesn't solve this problem
>when you are trying to compile with two non-C languages, but for just one it's
>fine.

I've often used C as a fron end to Fortran to allow the use of command-line
arguments to the program call, and pass most or all of these options
(possibly parsed & manipulated by C) to my fortran routine. 

Is there a common way of getting command-line arguments / flags to fortran
in a more direct manner?

	--M.

zifrony@TAURUS.BITNET (06/16/89)

Most environments I know, which include DG AOS/VS, VMS and UNIX have compatible
compilers, meaning you can interleave objects originating from different
languages to create your load module.

Of course, when reading a FORTRAN routine from C, it is important to remember
that FORTRAN arguments are passed by reference, thus pointers have to be
passed.  In case of character type, I am not sure there is a simple C
equivalent, and maybe some sort of simulation through the use of "struct" is
necessary.

The loading of the FORTRAN library indeed poses a problem.  I don't know if it
is setteled in any system.

--
Doron Zifrony   E-mail:    BITNET:    zifrony@taurus.bitnet
Msc.  Student              INTERNET:  zifrony@Math.Tau.Ac.IL
Dept. of   CS              ARPA:      zifrony%taurus.bitnet@cunyvm.cuny.edu
Tel Aviv Univ.             UUCP:      ...!uunet!mcvax!humus!taurus!zifrony
Israel                     CSNET:     zifrony%taurus.bitnet%cunyvm.cuny.edu@
                                        csnet-relay
--
Disclaimer: I DON'T represent Tel Aviv University.  The opinions hereby
            expressed are solely my own.

jagan@zodiac.rutgers.edu (02/11/91)

This is the summary of my experiences in calling Fortran routines
from C main program in SUN OS 4.03.

1. I was getting the run-time error of segmentation violation
   at every WRITE statements in Fortran. There was no warning
   or error messages while compiling or linking. Initially I thought 
   it could be Fortran I/O initialization problem. But, the source
   of the problem was found to be the name of a function in C (scale),
   which clashed with a Fortran library subroutine by the same 
   name. There is a long list of Fortran library subroutine names.
   The credit for debugging should go to Mr. Jim Wade of SUN.

2. The SUN-3 debugger is good.  SUN-4(SPARC) gives problems 
   while using debugger.

Few more points about calling Fortran from C:

1. If the name of Fortran subroutine called from C main is "test",
   then use the statement "test_();" in C main for calling it.
   Here no arguments are passed to Fortran.

2. If you wish to pass large number of arguments to Fortran,
   the easier way could be to use "common" statement in Fortran.

   For example, to pass the following structure in C :
        struct object_data {
            float surface[50][12];
	    int   bound[50][50];
	    float intersect[80][8];
            int   vertex[80][15];
          } dbs_ ;
   Note: the underscore after the variable name dbs is required.
   Use the following statements at the begining of Fortran program:
     integer bound(50,50), vertex(15,80)
     real*4 surface(12,50), intersect(8,80)
     common /dbs/surface,bound,intersect,vertex

 3. Do not use any integer*2 declaration in Fortran for any common
    arguments. Also do not use any "short int" declarations in C,
    for any common arguments. I am aware of only these two, but there
    may be some more restrictions.

 4. For compiling use the "cc" command for both C and Fortran programs.
    The programs should be linked to Fortran and C library using options:
          -lF77 -lU77 -lI77 -lc -lm

 5. Call the routines "f_init();" at the begining of C main to
    initialize Fortran I/O , and "f_exit();" at the end of C main.

   I  wish to acknowledge the help of Mr. Keith Bierman of SUN.
Also many other people gave me suggestions for which I am grateful.


Jagan
jagannat@caip.rutgers.edu
Rutgers University, New Jersey.