To Index

 Documented in Volume 1 of the UNIX Programmers Manual.
 See /usr/doc/f77 on 4.2 BSD systems for additional online documentation on this.

 This is the Fortran compiler for the ANSI 77 Standard.


 % f77 -c f77sourcename.f
  will compile f77sourcename.f, listing errors if any, generating an
  object module named f77sourcename.o if no errors.


 % f77 *.o -o executablename
  will collect all files in the current directory which end with '.o'
  and attempt to link them together with the loader. The resulting
  executable will be stored into the file 'executablename'.

 From Jeff Bowles    Lisle, IL    jab@uokvax.UUCP
    Do you have FORTRAN programs or FORTRAN subroutines/functions that you
 have to access from C?
    If you need to call a C routine from FORTRAN, and IF you're using the
 Unix f77(1) command, it's fairly straightforward:
       i) Remember that FORTRAN always passes references to the arguments;
       ii) You need to see eye-to-eye on types:
   	f77			C
   	integer			long (NOT "int", unless they're the same)
   	single precision 	float
   	double precision	double
   	character		one argument of address of the first byte,
 				one argument (by reference? I forget) of the
 				size of the "character argument".
       iii) If a routine is "gorp" in f77(1), it's "gorp_" in C; this was
       to edit
 things like "sine" not conflict for problems with ii)
       above.
    Now, the other direction is harder.... If the FORTRAN subprogram uses
 I/O, you have to drag in that library and the initialization stuff;
 otherwise, you might have to ANYHOW for the error messages that FORTRAN
 can output.
   You can look to see what libraries FORTRAN wants, such as "-LI77",
 '-LF77', "-lm" and so on.
   Beware of the program in which YOU write to "stdout" and then call a
 FORTRAN routine that writes to "stdout", aka "unit 6".

 From Steve Satterfield  brl-bmd!usna!steve
   Below are two examples of a C main program calling a f77 subroutine.
 Each example has a makefile, a C main and a f77 subroutine. You can
 edit this into the appropriate files and try them. We discovered these
 techniques by looking through the f77 source and they work for 4.2
 and V7.
   The normal f77 documentation describes the data types required for
 parameter passing when callin C from f77. This description also applies
 for the other direction. However, the problem we discovered when we first
 called a f77 subroutine from C is not described.  The problem is that
 I/O in the subroutine will not work unless the proper f77 things are done.
    In method 1, the actual 'main' program is supplied by f77 and your
 'main' is really called as a function named MAIN_. We generally
 use method 2 since it allows normal command line arguements to be used.
    These methods work for 4.2 and V7.

  METHOD 1:

 ======= makefile ==========

 main: main.o sub.o
 	f77 -o main main.o sub.o

 ======= main.c ============

 /* This is a main C routine that calls a f77 subroutine */
 MAIN_()
 {
 	int a,b,c;
 	a = 2;
 	b = 2;
 	c = 0;
 	printf("Calling sub\n");
 	sub_(&a,&b,&c);
 	printf("Returned from sub, c = %d\n",c);
 }

 ======= sub.f ==============

 	subroutine sub(a,b,c)
 	integer a,b,c
 	c = a+b
 	write(6,*) 'sub executing'
 	return
 	end


  METHOD 2:

 ======= makefile ===========

 main: main.o sub.o
 	cc -o main main.o sub.o -lF77 -lI77

 ======= main.c =============

 /* This is a main C routine the calls a f77 subroutine */
 main()
 {
 	int a,b,c;
 	f_init(); /* Required f77 initialization */
 	a = 2;
 	b = 2;
 	c = 0;
 	printf("Calling sub\n");
 	sub_(&a,&b,&c);
 	printf("Returned from sub, c = %d\n",c);
 	f_exit(); /* Required f77 clean up */
 }

 ======= sub.f ===============

 	subroutine sub(a,b,c)
 	integer a,b,c
 	c = a+b
 	write(6,*) "sub executing"
 	return
 	end


 From: mather@uiucdcs!uicsl!mather
 Subject: Re: Re: C calls FORTRAN subroutine
 Some not-too-well-known info:
  1) opening a file with "open(unit=n)" creates a file "fort.n"
 	unless ioinit has been used to change the default. ioinit(3F)
 	claims that there is no automatic filename association for
 	fortran logical units, but there is. In libI77, see err.c.
  2) It is difficult to pass C file descriptors to f77 as unit #s
 	and visa versa.
  3) Opening a file as "open(unit=n,file='/dev/tty')"  will put all output
 	written on unit n to your tty. Impossible to separate standard
 	output and standard error, however. I placed this open statement
 	prior to the write and it worked, but this isn't good if you call
 	this routine more than once, since it isn't nice to reopen a file
 	if it is already open. It should be closed first. But closing,
 	then opening puts the pointer at the beginning of the file (unless
 	ioinit is used to make files appendable).
 Calling C from FORTRAN is nice, but going the other way is a real pain,
 especially since you have to include all of the libF77 and libI77 junk.


 From: Kevin W. Thomas ...!ctvax!uokvax!uokmet!kwthomas
      There is a nice little trick that I've discovered.... If you have a
 C main program that calls FORTRAN routines, use "MAIN__()" instead of
 "main()", then compile with f77!  The linking is done for you.....


 From: joels@tektronix.UUCP (Joel Swank)
 Subject: Re: Re: C calls FORTRAN subroutine
  > Regarding the fellow who calls a FORTRAN subroutine from his C
  > program and is then unable to do I/O from within the FORTRAN
  > subroutine:
   I had this problem under 4.2bsd and I found that output was going to
 a file called fort.6. I circumvented the problem using a symbolic link:

      % ln -s /dev/tty fort.6

   Just execute this command before running the program, and output will
 go to the terminal.


 From: donn@utah-gr.UUCP (Donn Seeley)
 Subject: Re: C calls FORTRAN subroutine
 (from the original article by Aldrin Leung):
    PROBLEM: When these routines are compiled, loaded together and run,
 they print nothing.
    In the C program, I have:

 	#include 
 	main()
 	{
 	try_()
 	}

   In the Fortran program, I have:

 	subroutine try
 	write (6,100)
 	100   format ("subprogram")
 	end

    SOLUTION: The problem here is that f77's I/O system needs to be 'primed'.
 The standard f77 main() routine does this for you, but if you substitute
 your own C main() routine then you have to do the 'priming' yourself.
    There is an f77 I/O clean-up routine which you can call too (it's
 not as important, though).  Without the 'priming', f77 I/O (at least
 on pre-defined units) will have no effect.  A demonstration of the
 the use of the priming and clean-up routines appears below.
    Since f77 uses the C stdio library, you can mix C and f77 I/O by using
 stdio in your C routines rather than straight Unix system calls.  Since
 it may be difficult to predict which stdio file pointers are associated
 with which f77 unit numbers, it's probably a good idea to stick with
 'stdin', 'stdout' and 'stderr' when doing C I/O.
    One other thing that is useful to have is a MAIN_() routine.  This is
 normally created by f77 when it compiles the MAIN section of a program,
 but if you replace the f77 main() with a C main(), it never gets
 defined and f77 will complain about it if you use f77 to compile or
 load your program.  (Yes, f77 will compile C files, one of its many
 peculiar features.  Yes, this is useful because it means you can get
 all of the f77 libraries without having to specify them explicitly, as
 you would if you loaded your C and f77 objects 'by hand'.  Again, see
  below for an example of this.)
    Here's an example that demonstrates all of these features.
 Put the following code in a file 'c_main.c':

 	/* PROGRAM: c_main.c */
 	# include	
 	main( argc, argv, envp )
 		int		argc;
 		char		**argv;
 		char		**envp;
 	{
 		/* Process your arguments and environment here.  */

 		/* Prime the f77 I/O routines, call MAIN_(), and clean up.  */
 		f_init();
 		MAIN_();
 		f_exit();
 		exit( 0 );
 	}	 /* END MAIN */
 	MAIN_()  	/* Call various f77 and C routines. */
   	{
 		c_routine();
 		f77routine_();
   	}	 /* END _MAIN */
   	c_routine()
   	{
 		printf( "First some C I/O, then" );
   	} /* END PROGRAM */

  Put the following code in a file named 'f77_routines.f':

 	subroutine f77routine()
 	print *, 'some f77 I/O.'
 	return
 	end

  Then compile the two files like this:

  % f77 c_main.c f77_routines.f -o cf
  c_main.c:
  f77_routines.f:
     f77routine:
  %

  When you run the program, you get:

  % ./cf
  First some C I/O, then  some f77 I/O.
  %


 From: woods@hao.UUCP (Greg Woods) sdcsvax!sdcrdcf!trwrb!cepu!hao!woods
 Subject: Re: binary i/o problem
 > When there is no filename, the filename defaults
 > to "fort.unitnumber", which explains the error message (fort.5 does
 > not exist, hence is empty, so the first read gets EOF).  I almost
 > replied saying to  "open(5, file='/dev/tty',form='unformatted',...)",
 > but I don't think this will work if you use a pipe to enter the data.
 > I think in all cases /dev/tty is connected to the
 > terminal.  Does anyone have any other ideas?
    Yes. Use the isatty(3F) function which tells you whether standard
 input is a terminal or not. If so, your open will work fine. If
 not, don't ever close unit 5.
    P.S. I gave up on FORTRAN I/O a long time ago. We solved this problem here
 by implementing a library of trivial C functions to give us access to the
 system calls we needed. For example:

 	int uread_(fd,addr,bytes) int *fd; char *addr; int *bytes;
 	{ return(read(*fd,addr,*bytes); }

   This can now be called from FORTRAN under BSD just like a read call in C.
 Deals directly with file descriptors so no messing with FORTRAN I/O
 conventions. The disadvantage, of course, is that it's not meaningless
 on a non-UNIX system and non-portable to systems that don't allow FORTRAN
 and C to call each other.

 From: woods@hao.UUCP (Greg Woods)
 Subject: Re: pipe breaking
 Organization: High Altitude Obs./NCAR, Boulder CO
    PROBLEM:
 >  This fortran program accepts the uncompacted data from standard input
 >  via an unformatted read statement and plots it; it exits from the
 >  plotting loop when an EOF condition is detected.  At this point I
 >  want the program to accept input from the keyboard; however, it
 >  continues to read from the pipe.  Do you have any advice on how I
 >  can redirect the input once the EOF is reached?  Thanks for your support.

   This one is not too hard. You can catch the EOF, close unit 5, and then
 reopen it to read from the terminal. The code looks like:

       read(5,end=100) ...
 c jumps to statement label 100 when EOF sensed
       ....
       100  close(unit=5)
 c  close pipe
       open(unit=5,file='/dev/tty')
 c  reopen unit 5 to terminal
       read(5,...
 c read from terminal


  See man(3f) for fortran documentation
  See also efl(1) - Extended fortran Language
  See also f77(1) - fortran 77 compiler
  See also fpr(1) - print fortran file
  See also fsplit(1) - split a multi-routine fortran file into individual files
  See also ratfor(1) - rational fortran dialect
  See also struct(1) - structure fortran programs
  See also intro(3f) - introduction to fortran library functions
  See also ioinit(3f) - change fortran f77 I/O initialization
  See also putc, fputc (3f)- write a character to a fortran logical unit
  See also topen,tclose,tread,twrite,trewin,tskipf,tstate(3f) - f77 tape I/O

To Index