|
|
1.1 root 1: . \"define f2c % "\f(CWf2c\fP" %
2: . \"define F2c % "\f(CWF2c\fP" %
3: .de Bp
4: .ft R
5: .sp .5
6: .in \w'\(bu\ 'u
7: .ti 0
8: \(bu\ \c
9: ..
10: .EQ
11: define dollar % "\f(CW$\fP" %
12: delim $$
13: define f2c % "f\|2c" %
14: define F2c % "F\^2c" %
15: define libF77 % "libF77" %
16: define libI77 % "libI77" %
17: define LibF77 % "LibF77" %
18: define LibI77 % "LibI77" %
19: .EN
20: .TL
21: A Fortran to C Converter
22: .AU
23: S. I. Feldman
24: .AI
25: Bellcore
26: Morristown, NJ 07960
27: .AU
28: David M. Gay
29: .AI
30: .MH
31: .AU
32: Mark W. Maimone
33: .AI
34: Carnegie-Mellon University
35: Pittsburgh, PA 15213
36: .AU
37: N. L. Schryer
38: .AI
39: .MH
40: .AB
41: We describe $f2c$, a program that translates Fortran 77
42: into C or C++. $F2c$ lets one portably mix C and Fortran
43: and makes a large body of well-tested Fortran
44: source code available to C environments.
45: .AE
46: .SH
47: 1. INTRODUCTION
48: .PP
49: Automatic conversion of Fortran 77
50: .[ [
51: ANSI FORTRAN 1978
52: .]]
53: to C
54: .[ [
55: Kernighan Ritchie 1978
56: .]
57: .[
58: Kernighan Ritchie 1988
59: .]]
60: is desirable for
61: several reasons. Sometimes it is useful to run a
62: well-tested Fortran program on a machine that has a C
63: compiler but no Fortran compiler. At other times, it
64: is convenient to mix C and Fortran. Some things are
65: impossible to express in Fortran 77 or are harder
66: to express in Fortran than in C
67: (e.g. storage management, some character operations,
68: arrays of functions, heterogeneous data structures,
69: and calls that depend on the operating system),
70: and some programmers simply prefer C to Fortran.
71: There is a large body of well tested
72: Fortran source code for carrying out a wide variety of
73: useful calculations, and it is sometimes desirable to
74: exploit some of this Fortran source in a C environment.
75: Many vendors provide some way of mixing C and Fortran, but
76: the details vary from system to system.
77: Automatic Fortran to C conversion lets one create a
78: .I portable
79: C program that exploits Fortran source code.
80: .PP
81: A side benefit of automatic Fortran 77 to C conversion is that
82: it allows such tools as
83: .I cyntax (1)
84: and
85: .I lint (1)
86: \
87: .[[
88: v101
89: .]]
90: to provide Fortran 77 programs with some of the consistency
91: and portability checks that the Pfort Verifier
92: .[ [
93: Ryder 1974
94: .]]
95: provided to Fortran 66 programs.
96: The consistency checks
97: detect errors in calling sequences
98: and are thus a boon to debugging.
99: .PP
100: This paper describes $f2c$, a Fortran 77 to C converter
101: based on Feldman's original $f77$ compiler
102: .[ [
103: Feldman Weinberger Portable Fortran
104: .]].
105: We have used $f2c$ to convert various large programs and
106: subroutine libraries to C automatically (i.e., with no manual intervention);
107: these include the \s-2PORT3\s+2 subroutine library (\s-2PORT1\s+2
108: is described in
109: .[ [
110: Fox Hall Schryer Algorithm 1978
111: .]
112: .[
113: Fox Hall Schryer port 1978
114: .]]),
115: MINOS
116: .[ [
117: Murtagh Saunders 1987
118: .]],
119: and Schryer's floating-point test
120: .[ [
121: Schryer floating
122: .]].
123: The floating-point test is of particular interest, as it relies
124: heavily on correct evaluation of parenthesized expressions and
125: is bit-level self-testing.
126: .PP
127: As a debugging aid, we sought bit-level compatibility between
128: objects compiled from the C produced by $f2c$ and objects
129: produced by our local $f77$ compiler. That is, on the VAX
130: where we developed $f2c$, we sought to make it impossible to
131: tell by running a Fortran program whether some of its
132: modules had been compiled by $f2c$ or
133: all had been compiled by $f77$. This meant that $f2c$
134: should follow the same calling conventions as $f77$
135: .[ [
136: Feldman Weinberger Portable Fortran
137: .]]
138: and should use $f77$'s support libraries, $libF77$ and $libI77$.
139: .PP
140: Although we have tried to make $f2c$'s output reasonably readable,
141: our goal of strict compatibility with $f77$ implies some nasty
142: looking conversions. Input/output statements, in particular,
143: generally get expanded into
144: a series of calls on routines in $libI77$, $f77$'s I/O library.
145: Thus the C output of $f2c$ would probably be something of a nightmare
146: to maintain as C; it would be much more sensible to maintain the original
147: Fortran, translating it anew each time it changed. Some commercial
148: vendors, e.g., those listed in Appendix A,
149: seek to perform translations yielding C that one
150: might reasonably maintain directly; these translations generally
151: require some manual intervention.
152: .PP
153: The rest of this paper is organized as follows.
154: Section 2 describes the interlanguage conventions used by $f2c$ (and $f77$).
155: \(sc3 summarizes some extensions to Fortran 77 that $f2c$ recognizes.
156: . \"The extensions to Fortran 77 that $f2c$ recognizes are summarized in \(sc3.
157: Example invocations of $f2c$ appear in \(sc4.
158: \(sc5 illustrates various details of $f2c$'s translations, and
159: \(sc6 considers portability issues.
160: \(sc7 discusses the generation and use of
161: .I prototypes ,
162: which can be used both by C++ and ANSI C compilers and by
163: $f2c$ to check consistency of calling sequences.
164: \(sc8 describes our experience with
165: an experimental $f2c$ service provided by $netlib$
166: .[ [
167: Dongarra Grosse 1987
168: .]],
169: and \(sc9 considers possible extensions.
170: Appendix A lists some vendors who offer
171: conversion of Fortran to C that one might maintain as C.
172: Finally, Appendix B contains a $man$ page telling how to use $f2c$.
173: .SH
174: 2. INTERLANGUAGE CONVENTIONS
175: .PP
176: Much of the material in this section is taken from
177: .[ [
178: Feldman Weinberger Portable Fortran
179: .]].
180: .SH
181: Names
182: .PP
183: An $f2c$ extension
184: inspired by Fortran 90 (until recently called Fortran 8x
185: .[ [
186: Fort8x
187: .]])
188: is that long names are allowed ($f2c$ truncates names that are longer
189: than 50 characters), and names may contain underscores. To avoid conflict
190: with the names of library routines and with names that $f2c$ generates,
191: Fortran names may have one or two underscores appended.
192: Fortran names are forced to lower case (unless the
193: .CW \%-U
194: option described in Appendix B is in effect); external names, i.e., the names
195: of Fortran procedures and common blocks, have a single underscore appended
196: if they do not contain any underscores and have a pair of underscores
197: appended if they do contain underscores.
198: Thus Fortran subroutines named
199: .CW ABC ,
200: .CW A_B_C ,
201: and
202: .CW A_B_C_
203: result in C functions named
204: .CW abc_ ,
205: .CW a_b_c_\|\^_ ,
206: and
207: .CW a_b_c_\|\^_\|\^_ .
208: .SH
209: Types
210: .PP
211: The table below shows
212: corresponding Fortran and C declarations;
213: the C declarations use types defined in
214: .CW f2c.h ,
215: a header file upon which $f2c$'s translations rely.
216: The table also shows the C types defined in the standard
217: version of
218: .CW f2c.h .
219: .KS
220: .TS
221: center box;
222: c c c
223: l l l.
224: Fortran C standard \f(CWf2c.h\fP
225: .sp .5
226: integer\(**2 x shortint x; short int x;
227: integer x integer x; long int x;
228: logical x long int x; long int x;
229: real x real x; float x;
230: double precision x doublereal x; double x;
231: complex x complex x; struct { float r, i; } x;
232: double complex x doublecomplex x; struct { double r, i; } x;
233: character\(**6 x char x[6]; char x[6];
234: .TE
235: .KE
236: By the rules of Fortran,
237: .CW integer,
238: .CW logical,
239: and
240: .CW real
241: data occupy the same amount of memory, and
242: .CW "double precision"
243: and
244: .CW complex
245: occupy twice this amount; $f2c$
246: assumes that the types in the C column above are
247: chosen (in
248: .CW f2c.h )
249: so that these assumptions are valid.
250: The translations of the Fortran
251: .CW equivalence
252: and
253: .CW data
254: statements depend on these assumptions.
255: On some machines, one must modify
256: .CW f2c.h
257: to make these assumptions hold. See \(sc6 for examples
258: and further discussion.
259: .SH
260: Return Values
261: .PP
262: A function of type
263: .CW integer ,
264: .CW logical ,
265: or
266: .CW "double precision"
267: must be declared as a C function that returns the corresponding type.
268: If the
269: .CW \%-R
270: option is in effect (see Appendix B), the same is true
271: of a function of type
272: .CW real ;
273: otherwise, a
274: .CW real
275: function must be declared as a C function that returns
276: .CW doublereal ;
277: this hack facilitates our VAX regression testing, as it
278: duplicates the behavior of our local Fortran compiler ($f77$).
279: A
280: .CW complex
281: or
282: .CW "double complex"
283: function is equivalent to a C routine
284: with an additional
285: initial argument that points to the place where the return value is to be stored.
286: Thus,
287: .P1
288: complex function f( . . . )
289: .P2
290: is equivalent to
291: .P1
292: void f_(temp, . . .)
293: complex \(**temp;
294: . . .
295: .P2
296: A character-valued function is equivalent to a C routine with
297: two extra initial arguments:
298: a data address and a length.
299: Thus,
300: .P1
301: character\(**15 function g( . . . )
302: .P2
303: is equivalent to
304: .P1
305: g_(result, length, . . .)
306: char \(**result;
307: ftnlen length;
308: . . .
309: .P2
310: and could be invoked in C by
311: .P1
312: char chars[15];
313: . . .
314: g_(chars, 15L, . . . );
315: .P2
316: Subroutines are invoked as if they were
317: .CW int -valued
318: functions whose value specifies which alternate return to use.
319: Alternate return arguments (statement labels) are not passed to the function,
320: but are used to do an indexed branch in the calling procedure.
321: (If the subroutine has no entry points with alternate return arguments,
322: the returned value is undefined.)
323: The statement
324: .P1
325: call nret(\(**1, \(**2, \(**3)
326: .P2
327: is treated exactly as if it were the Fortran computed
328: .CW goto
329: .P1
330: goto (1, 2, 3), nret( )
331: .P2
332: .SH
333: Argument Lists
334: .PP
335: All Fortran arguments are passed by address.
336: In addition,
337: for every non-function argument that is of type character,
338: an argument giving the length of the value is passed.
339: (The string lengths are
340: .CW ftnlen
341: values, i.e.,
342: .CW "long int"
343: quantities passed by value). In summary, the order of arguments is:
344: extra arguments for complex and character functions,
345: an address for each datum or function, and a
346: .CW ftnlen
347: for each character argument (other than character-valued functions).
348: Thus, the call in
349: .P1
350: external f
351: character\(**7 s
352: integer b(3)
353: . . .
354: call sam(f, b(2), s)
355: .P2
356: is equivalent to that in
357: .P1
358: int f();
359: char s[7];
360: long int b[3];
361: . . .
362: sam_(f, &b[1], s, 7L);
363: .P2
364: Note that the first element of a C array always has subscript zero,
365: but Fortran arrays begin at 1 by default.
366: Because Fortran arrays are stored in column-major order, whereas
367: C arrays are stored in row-major order,
368: $f2c$ translates multi-dimensional Fortran arrays into one-dimensional
369: C arrays and issues appropriate subscripting expressions.
370: .SH
371: 3. EXTENSIONS TO FORTRAN 77
372: .PP
373: Since it is derived from $f77$, $f2c$ supports all of the $f77$ extensions
374: described in
375: .[ [
376: Feldman Weinberger Portable Fortran
377: .]].
378: $F2c$'s extensions include the following.
379: .Bp
380: Type
381: .CW "double complex"
382: (alias
383: .CW "complex*16" )
384: is a double-precision version of
385: .CW complex .
386: Specific intrinsic functions for
387: .CW "double complex"
388: have names that start with
389: .CW z
390: rather than
391: .CW c .
392: An exception to this rule is
393: .CW dimag ,
394: which returns the imaginary part of a
395: .CW "double complex"
396: value;
397: .CW imag
398: is the corresponding generic intrinsic function.
399: The generic intrinsic function
400: .CW real
401: is extended so that it returns the real part of a
402: .CW "double complex"
403: value as a
404: .CW "double precision"
405: value;
406: .CW dble
407: is the specific intrinsic function that does this job.
408: .Bp
409: The ``types'' that may appear in an
410: .CW implicit
411: statement include
412: .CW undefined ,
413: which implies that variables
414: whose names begin with the associated letters
415: must be explicitly declared in a type statement. $F2c$ also
416: recognizes the Fortran 90 statement
417: .P1
418: implicit none
419: .P2
420: as equivalent to
421: .P1
422: implicit undefined(a-z)
423: .P2
424: The command-line option
425: .CW \%-u
426: has the effect of inserting
427: .P1
428: implicit none
429: .P2
430: at the beginning of each Fortran procedure.
431: .Bp
432: Procedures may call themselves recursively, i.e.,
433: may call themselves either directly or indirectly
434: through a chain of other calls.
435: .Bp
436: The keywords
437: .CW static
438: and
439: .CW automatic
440: act as ``types'' in type and implicit statements;
441: they specify storage classes.
442: There is exactly one copy of each
443: .CW static
444: variable, and such variables retain their values between
445: invocations of the procedure in which they appear.
446: On the other hand, each invocation of a procedure gets
447: new copies of the procedure's
448: .CW automatic
449: variables.
450: .CW Automatic
451: variables may not appear in
452: .CW equivalence ,
453: .CW data ,
454: .CW namelist ,
455: or
456: .CW save
457: statements. The command-line option
458: .CW \%-a
459: changes the default storage class from
460: .CW static
461: to
462: .CW automatic
463: (for all variables except those that appear in
464: .CW common ,
465: .CW data ,
466: .CW equivalence ,
467: .CW namelist ,
468: or
469: .CW save
470: statements).
471: .Bp
472: A tab in the first 6 columns signifies that the current line is
473: a free-format line, which may extend beyond column 72.
474: An ampersand
475: .CW &
476: in column 1 indicates that the current line is a free-format
477: continuation line. Lines that have neither an ampersand in column 1
478: nor a tab in the first 6 columns are treated as Fortran 77 fixed-format
479: lines: if shorter than 72 characters, they are padded on the right
480: with blanks until they are 72 characters long; if longer than 72
481: characters, the characters beyond column 72 are discarded.
482: After taking continuations into account,
483: statements may be up to 1320 characters long; this is the only
484: constraint on the length of free-format lines. (This limit is
485: implied by the Fortran 77 standard, which allows at most 19 continuation lines;
486: $1320 ~=~ (1^+^19) ~times~ 66$.)
487: .Bp
488: Aside from quoted strings, $f2c$ ignores case (unless the
489: .CW \%-U
490: option is in effect).
491: .Bp
492: The statement
493: .P1
494: include 'stuff'
495: .P2
496: is replaced by the contents of the file
497: .CW stuff.
498: .CW Include s
499: may be nested to a reasonable depth, currently ten.
500: The command-line option
501: .CW \%-!I
502: disables
503: .CW include s;
504: this option is used by the $netlib$ $f2c$
505: service described in \(sc8 (for which
506: .CW include
507: obviously makes no sense).
508: .Bp
509: $F77$ allows binary, octal, and hexadecimal constants
510: to appear in
511: .CW data
512: statements; $f2c$ goes somewhat further, allowing
513: such constants to appear anywhere; they are treated just
514: like a decimal integer constant having the equivalent value.
515: Binary, octal, and hexadecimal constants may assume one of
516: two forms: a letter followed by a quoted string of digits,
517: or a decimal base, followed by a sharp sign
518: .CW # ,
519: followed by a string of digits (not quoted). The letter is
520: .CW b
521: or
522: .CW B
523: for binary constants,
524: .CW o
525: or
526: .CW O
527: for octal constants, and
528: .CW x ,
529: .CW X ,
530: .CW z ,
531: or
532: .CW Z
533: for hexadecimal constants. Thus, for example,
534: .CW z'a7' ,
535: .CW 16#a7 ,
536: .CW o'247' ,
537: .CW 8#247 ,
538: .CW b'10100111'
539: and
540: .CW 2#10100111
541: are all treated just like the integer
542: .CW 167 .
543: .Bp
544: For compatibility with C, quoted strings may contain the following
545: escapes:
546: .TS
547: center box;
548: lFCW l a lFCW l.
549: \e0 null \ \en newline
550: \e\e \e \ \er carriage return
551: \eb backspace \ \et tab
552: \ef form feed \ \ev vertical tab
553: .sp .5
554: .T&
555: aFCW l s s s.
556: \e' apostrophe (does not terminate a string)
557: \e" quotation mark (does not terminate a string)
558: \e\fIx\fP \fIx\fR, where \fIx\fR is any other character
559: .TE
560: The
561: .CW \%-!bs
562: option tells $f2c$ not to recognize these escapes.
563: Quoted strings may be delimited either by double quotes (\ \f(CW"\fR\ )
564: or by single quotes (\ \f(CW\(fm\fR\ ); if a string starts with
565: one kind of quote, the other kind may be embedded in the string
566: without being repeated or quoted by a backslash escape.
567: Where possible, translated strings are null-terminated.
568: .Bp
569: Hollerith strings are treated as character strings.
570: .Bp
571: In
572: .CW equivalence
573: statements, a multiply-dimensioned array may be given a single
574: subscript, in which case the missing subscripts are taken to be 1
575: (for backward compatibility with Fortran 66)
576: and a warning message is issued.
577: .Bp
578: In a formatted read of non-character variables, the I/O
579: library ($libI77$) allows a field to be terminated by a comma.
580: .Bp
581: Type
582: .CW real*4
583: is equivalent to
584: .CW real ,
585: .CW integer*4
586: to
587: .CW integer ,
588: .CW real*8
589: to
590: .CW "double precision" ,
591: .CW complex*8
592: to
593: .CW complex ,
594: and, as stated before,
595: .CW complex*16
596: to
597: .CW "double complex" .
598: .Bp
599: The type
600: .CW integer*2
601: designates short integers (translated to type
602: .CW shortint ,
603: which by default is
604: .CW "short int" ).
605: Such integers are expected to occupy half a ``unit'' of storage.
606: The command-line options
607: .CW \%-I2
608: and
609: .CW \%-i2
610: turn type
611: .CW integer
612: into
613: .CW integer*2 ;
614: see the $man$ page (appendix B) for more details.
615: .Bp
616: The binary intrinsic functions
617: .CW and ,
618: .CW or ,
619: .CW xor ,
620: .CW lshift ,
621: and
622: .CW rshift
623: and the unary intrinsic function
624: .CW not
625: perform bitwise operations on
626: .CW integer
627: or
628: .CW logical
629: operands. For
630: .CW lshift
631: and
632: .CW rshift ,
633: the second operand tells how many bits to
634: shift the first operand.
635: .Bp
636: $LibF77$ provides two functions for accessing command-line arguments:
637: .CW iargc(dummy)
638: returns the number of command-line arguments (and ignores its argument);
639: .CW getarg(k,c)
640: sets the character string
641: .CW c
642: to the $k$th command-line argument (or to blanks if $k$ is out of range).
643: .Bp
644: Variable,
645: .CW common ,
646: and procedure names may be arbitrarily long, but they
647: are truncated after the 50th character. These names may
648: contain underscores (in which case their translations will
649: have a pair of underscores appended).
650: .Bp
651: MAIN programs may have arguments, which are ignored.
652: .Bp
653: .CW Common
654: variables may be initialized by a
655: .CW data
656: statement in any module, not just in a
657: .CW "block data"
658: subprogram.
659: .Bp
660: The label may be omitted from a
661: .CW do
662: loop if the loop
663: is terminated by an
664: .CW enddo
665: statement.
666: .Bp
667: Unnamed Fortran 90
668: .CW "do while"
669: loops are allowed.
670: Such a loop begins with a statement of the form
671: .ce
672: \f(CWdo \fR[\fIlabel\^\fR] [\f(CW,\fR] \f(CWwhile(\fIlogical expression\f(CW)\fR
673: and ends either after the statement labelled by $label$ or after a matching
674: .CW enddo .
675: .Bp
676: $F2c$ recognizes the Fortran 90 synonyms
677: .CW < ,
678: .CW <= ,
679: .CW == ,
680: .CW >= ,
681: .CW > ,
682: and
683: .CW <>
684: for the Fortran comparison operators
685: .CW .LT. ,
686: .CW .LE. ,
687: .CW .EQ. ,
688: .CW .GE. ,
689: .CW .GT. ,
690: and
691: .CW .NE.
692: .Bp
693: \f(CWNamelist\fR
694: works as in Fortran 90
695: .[ [
696: Fort8x
697: .]],
698: with a minor restriction on
699: .CW namelist
700: input: subscripts must have the form
701: .ce
702: $subscript$ [ : $subscript$ [ : $stride$ ] ]
703: For example, the Fortran
704: .P1
705: integer m(8)
706: real x(10,10)
707: namelist /xx/ m, x
708: \&. . .
709: read(*,xx)
710: .P2
711: could read
712: .P1
713: &xx x(1,1) = 2, x(1:3,8:10:2) = 1,2,3,4,5,6 m(7:8) = 9,10/
714: .P2
715: but would elicit error messages on the inputs
716: .P1
717: &xx x(:3,8:10:2) = 1,2,3,4,5,6/
718: &xx x(1:3,8::2) = 1,2,3,4,5,6/
719: &xx m(7:) = 9,10/
720: .P2
721: (which inputs would be legal in Fortran 90).
722: For compatibility with the
723: .CW namelist
724: variants supplied by several vendors as Fortran 77 extensions,
725: $f2c$'s version of $libI77$ permits $dollar$ to be used instead of
726: .CW &
727: and
728: .CW /
729: in
730: .CW namelist
731: input. Thus the Fortran shown above could read
732: .P1
733: $dollar$xx x(1,1) = 2, x(1:3,8:10:2) = 1,2,3,4,5,6 m(7:8) = 9,10$dollar$end
734: .P2
735: .in 0
736: .Bp
737: Internal list-directed and namelist I/O are allowed.
738: .Bp
739: In an
740: .CW open
741: statement,
742: .CW name=
743: is treated as
744: .CW file= .
745: .Bp
746: Fortran 90 inline comments are allowed.
747: They start with a
748: .CW !
749: anywhere but column 6.
750: .in 0
751: .SH
752: 4. INVOCATION EXAMPLES
753: .PP
754: To convert the Fortran files
755: .CW main.f
756: and
757: .CW subs.f ,
758: one might use the UNIX\u\(rg\d command:
759: .P1
760: f2c main.f subs.f
761: .P2
762: This results in translated files suffixed with
763: .CW .c ,
764: i.e., the resulting C files are
765: .CW main.c
766: and
767: .CW subs.c .
768: To translate all the Fortran files in the current
769: directory, compile the resulting C,
770: and create an executable program named
771: .CW myprog ,
772: one might use the following pair of UNIX commands:
773: .P1
774: f2c *.f
775: cc -o myprog *.c -lF77 -lI77 -lm
776: .P2
777: The above
778: .CW -lF77
779: and
780: .CW -lI77
781: options assume that the ``standard'' Fortran support libraries
782: $libF77$ and $libI77$
783: are appropriate for use with $f2c$. On some systems this is
784: not the case (as further discussed in \(sc6); if one had
785: installed a combination of the appropriate $libF77$ and $libI77$
786: in the appropriate place, then the above example might become
787: .P1
788: f2c *.f
789: cc -o myprog *.c -lf2c -lm
790: .P2
791: Sometimes it is desirable to use $f2c$'s
792: .CW -R
793: option, which tells $f2c$ not to force all floating-point operations
794: to be done in double precision. (One might argue that
795: .CW -R
796: should be the default, but we find the current arrangement
797: more convenient for testing $f2c$.) With
798: .CW -R
799: specified, the previous example becomes
800: .P1
801: f2c -R *.f
802: cc -o myprog *.c -lf2c -lm
803: .P2
804: Sometimes it is desirable to translate several Fortran source
805: files into a single C file. This is easily done by using $f2c$
806: as a filter:
807: .P1
808: cat *.f | f2c >mystuff.c
809: .P2
810: The
811: .CW -A
812: option lets $f2c$ use ANSI C constructs
813: .[ [
814: ANSIC
815: .]],
816: which yields more readable C when
817: .CW character
818: variables are initialized. With both
819: .CW -A
820: and
821: .CW -R
822: specified, the last example becomes
823: .P1
824: cat *.f | f2c -A -R >mystuff.c
825: .P2
826: For use with C++
827: .[ [
828: Stroustrup C++ Programming Language 1986
829: .]],
830: one would specify
831: .CW -C++
832: rather than
833: .CW -A ;
834: the last example would then become
835: .P1
836: cat *.f | f2c -C++ -R >mystuff.c
837: .P2
838: The
839: .CW -C++
840: option gives ANSI-style headers and old-style C formatting
841: of character strings and
842: .CW float
843: constants (since some C++ compilers reject the ANSI versions
844: of these constructs).
845: .LP
846: With ANSI C, one can use
847: .I prototypes ,
848: i.e., a special syntax describing the calling sequences
849: of procedures, to help catch errors in argument passing. To
850: make using prototypes convenient, the
851: .CW -P
852: option causes $f2c$ to create a \fIfile\f(CW.P\fR of prototypes
853: for the procedures defined in
854: each input \fIfile\f(CW.f\fR (or \fIfile\f(CW.F\fR, i.e., the
855: suffix
856: .CW .f '' ``
857: or
858: .CW .F '' ``
859: is replaced by
860: .CW .P ''). ``
861: One could concatenate all relevant prototype files into
862: a header file and arrange for the header to be
863: .CW #include d
864: with each C file compiled.
865: Since
866: .CW -P
867: implies
868: .CW -A
869: unless
870: .CW -C++
871: is specified, one could
872: convert all the Fortran files in the current directory
873: to ANSI C
874: and get corresponding prototype files by issuing the command
875: .P1
876: f2c -P *.f
877: .P2
878: Several command options may be combined if none but perhaps the
879: last takes an argument; thus to specify
880: .CW -R
881: and get C++ prototypes for all the
882: files in the current directory, one could say either
883: .P1
884: f2c -C++ -P -R *.f
885: .P2
886: or
887: .P1
888: f2c -C++PR *.f
889: .P2
890: or
891: .P1
892: f2c -RPC++ *.f
893: .P2
894: \(em options can come in any order.
895: .LP
896: For numeric variables initialized by character data, the
897: .CW -W
898: option specifies the (machine-dependent!)
899: number of characters per word and is further discussed
900: in \(sc6. This option takes a numeric argument, as in
901: .CW -W8 ;
902: such an option must be listed either separately or at the end
903: of a string of other options, as in
904: .P1
905: f2c -C++RPW8 *.f
906: .P2
907: .SH
908: 5. TRANSLATION DETAILS
909: .PP
910: $F2c$ is based on the ancient $f77$ Fortran compiler of
911: .[ [
912: Feldman Weinberger Portable Fortran
913: .]].
914: That compiler produced a C parse-tree,
915: which it converted into input for the second pass of the
916: portable C compiler (PCC)
917: .[ [
918: Johnson portable compiler
919: .]].
920: The compiler has been used for many years and is the
921: direct ancestor of many current Fortran compilers.
922: Thus, it provided us with a solid base of Fortran knowledge
923: and a nearly complete C representation.
924: The converter $f2c$ is a copy of the $f77$ Fortran compiler
925: which has been altered to print out a C representation
926: of the program being converted.
927: The program $f2c$ is a \fIhorror\fP, based on ancient code and
928: hacked unmercifully.
929: Users are only supposed to look at its C output,
930: not at its appalling inner workings.
931: .PP
932: Here are some examples that illustrate $f2c$'s translations.
933: For starters, it is helpful to see a short but complete
934: example: $f2c$ turns the
935: Fortran inner product routine
936: .P1
937: .so dot.f
938: .P2
939: into
940: .P1
941: .so dot.c
942: .P2
943: The translated C always starts with a ``translated by f2c'' comment
944: and a
945: .CW #include
946: of
947: .CW f2c.h .
948: $F2c$ forces the variable and procedure names to lower-case and
949: appends an underscore to the external name
950: .CW dot
951: (to avoid possible conflicts with library names).
952: The parameter adjustments
953: .CW --x '' ``
954: and
955: .CW --y '' ``
956: account for the fact that C arrays start at index 0.
957: Unused labels are retained in comments for orienteering purposes.
958: Within a function, Fortran references to the function name are turned into
959: references to the local variable
960: .CW ret_val ,
961: which holds the value to be returned. Unless the
962: .CW -R
963: option is specified, $f2c$ converts the return type of
964: .CW real
965: function values to
966: .CW doublereal .
967: Because using the C ``op='' operators
968: leads to greater efficiency on some machines, $f2c$ looks for opportunities
969: to use these operators, as in the line
970: .CW "ret_val += ..." '' ``
971: above.
972: .PP
973: $F2c$ generally dispenses with superfluous parentheses: ANSI C
974: specifies a clear order of evaluation for floating-point expressions,
975: and $f2c$ uses the ANSI C rules to decide when parentheses are required
976: to faithfully translate a parenthesized Fortran expression.
977: Non-ANSI compilers are free to violate parentheses; by default, $f2c$ does
978: not attempt to break an expression into several statements to
979: foil pernicious non-ANSI C compilers. Thus, for example, the Fortran
980: .P1
981: x = a*(b*c)
982: y = (a*b)*c
983: .P2
984: becomes
985: .P1
986: x = a * (b * c);
987: y = a * b * c;
988: .P2
989: The
990: .CW \%-kr
991: and
992: .CW \%-krd
993: options cause $f2c$ to use temporary variables to force correct
994: evaluation order with non-ANSI C compilers.
995: .ig
996: If, for instance,
997: .CW a ,
998: .CW b ,
999: and
1000: .CW c ,
1001: are
1002: .CW real
1003: variables, then under
1004: .CW \%-kr
1005: the above Fortran results in
1006: .P1
1007: /* System generated locals */
1008: real r_1;
1009: \&. . .
1010: r_1 = b * c;
1011: x = a * r_1;
1012: r_1 = a * b;
1013: y = r_1 * c;
1014: .P2
1015: ..
1016: .PP
1017: Fortran I/O is complicated; like $f77$, $f2c$ converts
1018: a Fortran I/O statement into calls on the Fortran I/O library $libI77$.
1019: For Fortran
1020: .CW read s
1021: and
1022: .CW write s,
1023: there is generally one call to start the statement, one to end it,
1024: and one for each item read or written. Given the Fortran declarations
1025: .P1
1026: integer count(10)
1027: real val(10)
1028: .P2
1029: the Fortran
1030: .P1
1031: read(*,*) count, val
1032: .P2
1033: is turned into some header lines:
1034: .P1
1035: static integer c_\|\^_3 = 3;
1036: static integer c_\|\^_10 = 10;
1037: static integer c_\|\^_4 = 4;
1038: \&. . .
1039: /* Builtin functions */
1040: integer s_rsle(), do_lio(), e_rsle();
1041: \&. . .
1042: /* Fortran I/O blocks */
1043: static cilist io_\|\^_1 = { 0, 5, 0, 0, 0 };
1044: .P2
1045: and the executable lines
1046: .P1
1047: s_rsle(&io_\|\^_1);
1048: do_lio(&c_\|\^_3, &c_\|\^_10, (char *)&count[0], (ftnlen)sizeof(integer));
1049: do_lio(&c_\|\^_4, &c_\|\^_10, (char *)&val[0], (ftnlen)sizeof(real));
1050: e_rsle();
1051: .P2
1052: Implicit Fortran do-loops, e.g.
1053: .P1
1054: read(*,*) (count(i), val(i), i = 1, 10)
1055: .P2
1056: get turned into explicit C loops:
1057: .P1
1058: s_rsle(&io_\|\^_4);
1059: for (i = 1; i <= 10; ++i) {
1060: do_lio(&c_\|\^_3, &c_\|\^_1, (char *)&count[i - 1], (ftnlen)sizeof(integer));
1061: do_lio(&c_\|\^_4, &c_\|\^_1, (char *)&val[i - 1], (ftnlen)sizeof(real));
1062: }
1063: e_rsle();
1064: .P2
1065: The Fortran
1066: .CW end=
1067: and
1068: .CW err=
1069: specifiers make the resulting C even less readable, as they require
1070: tests to be inserted. For example,
1071: .P1
1072: read(*,*,err=10) count, val
1073: 10 continue
1074: .P2
1075: becomes
1076: .P1
1077: i_\|\^_1 = s_rsle(&io_\|\^_1);
1078: if (i_\|\^_1 != 0) {
1079: goto L10;
1080: }
1081: i_\|\^_1 = do_lio(&c_\|\^_3, &c_\|\^_10, (char *)&count[0], (ftnlen)sizeof(integer));
1082: if (i_\|\^_1 != 0) {
1083: goto L10;
1084: }
1085: i_\|\^_1 = do_lio(&c_\|\^_4, &c_\|\^_10, (char *)&val[0], (ftnlen)sizeof(real));
1086: if (i_\|\^_1 != 0) {
1087: goto L10;
1088: }
1089: i_\|\^_1 = e_rsle();
1090: L10:
1091: ;
1092: .P2
1093: .PP
1094: A Fortran routine containing $n$ \f(CWentry\fR statements
1095: is turned into $n^+^2$ C functions, a big one containing
1096: the translation of everything but the \f(CWentry\fR statements,
1097: and $n^+^1$ little ones that invoke the big one. Each little
1098: one passes a different integer to the big one to tell
1099: it where to begin; the big one starts with a switch
1100: that branches to the code for the appropriate entry.
1101: For instance, the Fortran
1102: .P1
1103: function sine(x)
1104: data pi/3.14159265358979324/
1105: sine = sin(x)
1106: return
1107: entry cosneg(y)
1108: cosneg = cos(y+pi)
1109: return
1110: end
1111: .P2
1112: is turned into the big procedure
1113: .P1
1114: doublereal sine_0_(n_\|\^_, x, y)
1115: int n_\|\^_;
1116: real *x, *y;
1117: {
1118: /* Initialized data */
1119:
1120: static real pi = (float)3.14159265358979324;
1121:
1122: /* System generated locals */
1123: real ret_val;
1124:
1125: /* Builtin functions */
1126: double sin(), cos();
1127:
1128: switch(n_\|\^_) {
1129: case 1: goto L_cosneg;
1130: }
1131:
1132: ret_val = sin(*x);
1133: return ret_val;
1134:
1135: L_cosneg:
1136: ret_val = cos(*y + pi);
1137: return ret_val;
1138: } /* sine_ */
1139: .P2
1140: and the little invoking procedures
1141: .P1
1142: doublereal sine_(x)
1143: real *x;
1144: {
1145: return sine_0_(0, x, (real *)0);
1146: }
1147:
1148: doublereal cosneg_(y)
1149: real *y;
1150: {
1151: return sine_0_(1, (real *)0, y);
1152: }
1153: .P2
1154: .LP
1155: Fortran
1156: .CW common
1157: regions are turned into C
1158: .CW struct s.
1159: For example, the Fortran declarations
1160: .P1
1161: common /named/ c, d, r, i, l
1162: complex c(10)
1163: double precision d(10)
1164: real r(10)
1165: integer i(10)
1166: logical m(10)
1167:
1168: if (m(i(2))) d(3) = d(4)/d(5)
1169: .P2
1170: result in
1171: .P1
1172: struct {
1173: complex c[10];
1174: doublereal d[10];
1175: real r[10];
1176: integer i[10];
1177: logical m[10];
1178: } named_;
1179:
1180: #define named_1 named_
1181: \&. . .
1182:
1183: if (named_1.m[named_1.i[1] - 1]) {
1184: named_1.d[2] = named_1.d[3] / named_1.d[4];
1185: }
1186: .P2
1187: Under the
1188: .CW -p
1189: option, the above
1190: .CW if
1191: statement becomes more readable:
1192: .P1
1193: \&. . .
1194: #define c (named_1.c)
1195: #define d (named_1.d)
1196: #define r (named_1.r)
1197: #define i (named_1.i)
1198: #define m (named_1.m)
1199: \&. . .
1200: if (m[i[1] - 1]) {
1201: d[2] = d[3] / d[4];
1202: .P2
1203: If the above
1204: .CW common
1205: block were involved in a
1206: .CW "block data"
1207: subprogram, e.g.
1208: .P1
1209: block data
1210: common /named/ c, d, r, i, l, m
1211: complex c(10)
1212: double precision d(10)
1213: real r(10)
1214: integer i(10)
1215: logical m(10)
1216: data c(1)/(1.0,0e0)/, d(2)/2d0/, r(3)/3e0/, i(4)/4/,
1217: * m(5)/.false./
1218: end
1219: .P2
1220: then the
1221: .CW struct
1222: would begin
1223: .CW "struct named_1_ {" '', ``
1224: and $f2c$ would issue a more elaborate
1225: .CW #define :
1226: .P1
1227: #define named_1 (*(struct named_1_ *) &named_)
1228:
1229: /* Initialized data */
1230:
1231: struct {
1232: complex e_1;
1233: doublereal fill_2[10];
1234: doublereal e_3;
1235: doublereal fill_4[9];
1236: real e_5;
1237: integer fill_6[10];
1238: integer e_7;
1239: integer fill_8[11];
1240: logical e_9;
1241: integer fill_10[5];
1242: } named_ = { (float)1., (float)0., {0}, 2., {0}, (float)3., {0}, 4,
1243: {0}, FALSE_ };
1244: .P2
1245: In this example, $f2c$ relies on C's structure initialization rules
1246: to supply zeros to the
1247: \f(CWfill_\fIn\fR
1248: arrays that take up the space for which no
1249: .CW data
1250: values were given. (The logical constants
1251: .CW TRUE_
1252: and
1253: .CW FALSE_
1254: are defined in
1255: .CW f2c.h .)
1256: .PP
1257: Character manipulations of multiple-character strings
1258: generally result in function calls. For example,
1259: the Fortran
1260: .P1
1261: character*(*) function cat(a,b)
1262: character*(*) a, b
1263: cat = a // b
1264: end
1265: .P2
1266: yields
1267: .P1
1268: \&. . .
1269: static integer c_\|\^_2 = 2;
1270:
1271: /* Character */ int cat_(ret_val, ret_val_len, a, b, a_len, b_len)
1272: char *ret_val;
1273: ftnlen ret_val_len;
1274: char *a, *b;
1275: ftnlen a_len;
1276: ftnlen b_len;
1277: {
1278:
1279: /* System generated locals */
1280: address a_\|\^_1[2];
1281: integer i_\|\^_1[2];
1282:
1283: /* Builtin functions */
1284: /* Subroutine */ int s_cat();
1285:
1286: /* Writing concatenation */
1287: i_\|\^_1[0] = a_len, a_\|\^_1[0] = a;
1288: i_\|\^_1[1] = b_len, a_\|\^_1[1] = b;
1289: s_cat(ret_val, a_\|\^_1, i_\|\^_1, &c_\|\^_2, ret_val_len);
1290: } /* cat_ */
1291: .P2
1292: Note how the return-value length
1293: .CW ret_val_len ) (
1294: and parameter lengths
1295: .CW a_len "" (
1296: and
1297: .CW b_len )
1298: are used.
1299: Single character operations are generally done in-line.
1300: For example, the body of the Fortran
1301: .P1
1302: character*1 function lastnb(x,n)
1303: character*1 x(n)
1304: lastnb = ' '
1305: do 10 i = n, 1, -1
1306: if (x(i) .ne. ' ') then
1307: lastnb = x(i)
1308: return
1309: end if
1310: 10 continue
1311: end
1312: .P2
1313: becomes
1314: .P1
1315: *ret_val = ' ';
1316: for (i = *n; i >= 1; --i) {
1317: if (x[i] != ' ') {
1318: *ret_val = x[i];
1319: return ;
1320: }
1321: /* L10: */
1322: }
1323: .P2
1324: .PP
1325: $F2c$ uses
1326: .CW struct s
1327: and
1328: .CW #define s
1329: to translate
1330: .CW equivalence s.
1331: For a complicated example showing the interaction of
1332: .CW data
1333: with
1334: .CW common ,
1335: .CW equivalence ,
1336: and, for good measure, Hollerith notation,
1337: consider the Fortran
1338: .P1
1339: common /cmname/ c
1340: complex c(10)
1341: double precision d(10)
1342: real r(10)
1343: integer i(10)
1344: logical m(10)
1345: equivalence (c(1),d(1),r(1),i(1),m(1))
1346: data c(1)/(1.,0.)/
1347: data d(2)/2d0/, r(5)/3e0/, i(6)/4/, m(7)/.true./
1348: call sam(c,d(1),r(2),i(3),m(4),14hsome hollerith,14)
1349: end
1350: .P2
1351: The resulting C is
1352: .P1
1353: \&. . .
1354: struct cmname_1_ {
1355: complex c[10];
1356: };
1357:
1358: #define cmname_1 (*(struct cmname_1_ *) &cmname_)
1359:
1360: /* Initialized data */
1361:
1362: struct {
1363: complex e_1;
1364: doublereal e_2;
1365: real e_3;
1366: integer e_4;
1367: logical e_5;
1368: integer fill_6[13];
1369: } cmname_ = { (float)1., (float)0., 2., (float)3., 4, TRUE_ };
1370:
1371:
1372: /* Table of constant values */
1373:
1374: static integer c_\|\^_14 = 14;
1375: .P2
1376: .P1
1377: /* Main program */ MAIN_\|\^_()
1378: {
1379:
1380: /* Local variables */
1381:
1382: #define d ((doublereal *)&cmname_1)
1383: #define i ((integer *)&cmname_1)
1384: #define l ((logical *)&cmname_1)
1385: #define r ((real *)&cmname_1)
1386: extern /* Subroutine */ int sam_();
1387:
1388: sam_(cmname_1.c, d, &r[1], &i[2], &m[3], "some hollerith", &c_\|\^_14, 14L);
1389: } /* MAIN_\|\^_ */
1390:
1391: #undef r
1392: #undef l
1393: #undef i
1394: #undef d
1395: .P2
1396: As this example shows, $f2c$ turns a Fortran MAIN program into
1397: a C function named
1398: .CW MAIN_\|\^_ .
1399: Why not
1400: .CW main ?
1401: Well, $libF77$ contains a C main routine that arranges
1402: for files to be closed automatically when the Fortran program stops,
1403: arranges for an error message to be printed if a floating-point
1404: exception occurs, and arranges for the command-line argument
1405: accessing functions
1406: .CW iargc
1407: and
1408: .CW getarg
1409: to work properly. This C main routine invokes
1410: .CW MAIN_\|\^_ .
1411: .SH
1412: 6. PORTABILITY ISSUES
1413: .PP
1414: Three portability issues are relevant to $f2c$:
1415: the portability of the support libraries ($libF77$ and $libI77$)
1416: upon which the translated C programs rely,
1417: that of the converter $f2c$ itself,
1418: and that of the C it produces.
1419: .PP
1420: Regarding the first issue,
1421: some vendors (e.g., Sun and MIPS) have changed the calling conventions for
1422: their $libI77$ from the original conventions (those of
1423: .[ [
1424: Feldman Weinberger Portable Fortran
1425: .]]).
1426: Other vendors (e.g., MIPS) have changed the $libF77$ calling conventions
1427: (e.g., for
1428: .CW complex -valued
1429: functions).
1430: Thus, having libraries $libF77$ and $libI77$
1431: or otherwise having library routines with the names
1432: that $f2c$ expects is insufficient.
1433: When using a machine whose vendor provides but has gratuitously changed
1434: $libF77$ or $libI77$, one cannot safely mix objects compiled
1435: from the C produced by $f2c$ with objects compiled by the vendor's
1436: Fortran compiler, and one must use the correct libraries with
1437: programs translated by $f2c$. In such a case, the recommended procedure
1438: is to obtain source for the libraries (e.g. from
1439: .I netlib
1440: \(em see \(sc8), combine them into a single library, say
1441: .CW libf2c ,
1442: and install the library where it they can be conveniently accessed.
1443: On a UNIX system, for example, one might install
1444: .CW libf2c
1445: in
1446: .CW /usr/lib/libf2c.a ;
1447: then one could issue the command
1448: .P1
1449: cc *.c -lf2c -lm
1450: .P2
1451: to compile and link a program translated by $f2c$.
1452: .PP
1453: The converter itself is reasonably portable and has run successfully on Apollo,
1454: Cray, IBM, MIPS, SGI, Sun and DEC VAX equipment, all running some
1455: version of the UNIX operating system.
1456: However, we shall see that the C it produces may not be portable due to
1457: subtle storage management issues in Fortran 77.
1458: In any case, the C output of $f2c$ will run fine, at least if
1459: the \f(CW\%-W\fIn\fR option (see Appendix B) is used to set the
1460: number of characters per word correctly, and if C
1461: .CW double
1462: values may fall on an odd-word boundary.
1463: .PP
1464: The Fortran 77 standard says that \f(CWComplex\fP and \f(CWDouble Precision\fP
1465: objects occupy two ``units'' of space while other non-character data types
1466: occupy one ``unit.''
1467: It may be necessary to edit the header file
1468: .CW f2c.h
1469: to make these assumptions hold, if possible.
1470: On the Cray, for example,
1471: .CW float
1472: and
1473: .CW double
1474: are the same C types, and Fortran double precision, if
1475: available, would correspond to the C type
1476: .CW "long double" .
1477: In this case, changing the definition of
1478: .CW doublereal
1479: in
1480: .CW f2c.h
1481: from
1482: .P1
1483: typedef double doublereal;
1484: .P2
1485: to
1486: .P1
1487: typedef long double doublereal;
1488: .P2
1489: would be appropriate. For the Think C compiler on the
1490: Macintosh, on the other hand, this line would need to become
1491: .P1
1492: typedef short double doublereal;
1493: .P2
1494: .PP
1495: If your C compiler predefines symbols that could clash with
1496: translated Fortran variable names, then you should also
1497: add appropriate
1498: .CW #undef
1499: lines to
1500: .CW f2c.h .
1501: The current default
1502: .CW f2c.h
1503: provides the following
1504: .CW #undef
1505: lines for the following symbols:
1506: .TS
1507: center;
1508: lfCW lfCW lfCW lfCW lfCW lfCW.
1509: cray mc68020 sgi sun2 u370 u3b5
1510: gcos mips sparc sun3 u3b unix
1511: mc68010 pdp11 sun sun4 u3b2 vax
1512: .TE
1513: .PP
1514: As an extension to the Fortran 77 Standard, $f2c$
1515: allows noncharacter variables to be initialized with character
1516: data. This extension is inherently nonportable, as the number
1517: of characters storable per ``unit'' varies from machine to machine.
1518: Since 32 bit machines are the most plentiful, $f2c$
1519: assumes 4 characters per Fortran ``unit'', but this assumption
1520: can be overridden by the \f(CW\%-W\fIn\fR command-line option.
1521: For example,
1522: .CW \%-W8
1523: is appropriate for C that is to be run on Cray computers,
1524: since Crays store 8 characters per word.
1525: An example is helpful here: the Fortran
1526: .P1
1527: data i/'abcd'/
1528: j = i
1529: end
1530: .P2
1531: turns into
1532: .P1
1533: /* Initialized data */
1534:
1535: static struct {
1536: char e_1[4];
1537: } equiv_3 = { {'a', 'b', 'c', 'd'} };
1538:
1539: #define i (*(integer *)&equiv_3)
1540:
1541: static integer j;
1542:
1543: j = i;
1544: \&. . .
1545: #undef i
1546: .P2
1547: (Some use of
1548: .CW i ,
1549: e.g. ``\f(CWj = i\fR'', is necessary or $f2c$
1550: will see that
1551: .CW i
1552: is not used and will not initialize it.) If the target
1553: machine were a Cray and the string were
1554: .CW 'abcdefgh'
1555: or \f(CW"abcdefhg"\fR,
1556: then the Fortran would run fine, but the C produced by $f2c$ would only
1557: store \f(CW"abcd"\fR
1558: in i, $4$ being the default number of characters per word.
1559: The $f2c$ command-line option
1560: .CW \%-W8
1561: gives the correct initialization for a Cray.
1562: .PP
1563: The initialization above is clumsy, using $4$ separate characters.
1564: Using the option
1565: .CW -A ,
1566: for ANSI, produces
1567: .P1
1568: \&. . .
1569: } equiv_3 = { "abcd" };
1570: \&. . .
1571: .P2
1572: See Appendix B.
1573: .PP
1574: The above examples explain why the Fortran 77 standard excludes
1575: Hollerith data statements: the number of characters per word is
1576: not specified and hence such code is not portable even in Fortran.
1577: (Fortran that conservatively assumes only 1 or 2 characters per word is
1578: portable but messy. Note that Fortran 77 forbids the mixing, via
1579: .CW common ,
1580: .CW data ,
1581: or
1582: .CW equivalence ,
1583: of character and noncharacter types. Like many Fortran compilers,
1584: $f2c$ permits such nonportable mixing;
1585: initialization of numeric variables with Hollerith data is one
1586: example of this mixing.)
1587: .PP
1588: Some Fortran 66 programs pass Hollerith strings to
1589: .CW integer
1590: variables. $F2c$ treats a Hollerith string as a character string,
1591: but this may lead to bus errors on some systems if the character
1592: string winds up being improperly aligned. The
1593: .CW \%-h
1594: option instructs $f2c$ to try to give character variables
1595: and constants the same alignment as
1596: .CW integer s.
1597: Under
1598: .CW \%-h ,
1599: for example, the Fortran
1600: .P1
1601: call foo("a string")
1602: call goo(8ha string)
1603: .P2
1604: is translated to
1605: .P1
1606: static struct { integer fill; char val[8+1]; char fill2[3]; } c_b1_st = { 0,
1607: "a string" };
1608: #define c_b1 c_b1_st.val
1609: \&. . .
1610: foo_(c_b1, 8L);
1611: goo_(c_b1, 8L);
1612: \&. . .
1613: .P2
1614: .PP
1615: Some systems require that C values of type
1616: .CW double
1617: be aligned on a double-word boundary. Fortran
1618: .CW common
1619: and
1620: .CW equivalence
1621: statements may require some C
1622: .CW double
1623: values to be aligned on an odd-word boundary.
1624: On systems where double-word alignment is required,
1625: C compilers pad structures, if necessary, to arrange
1626: for the right alignment. Often such padding has no effect on
1627: the validity of $f2c$'s
1628: translation, but using
1629: .CW common
1630: or
1631: .CW equivalence ,
1632: it is easy to contrive examples in which
1633: the translated C works incorrectly.
1634: $F2c$ issues a warning message when double-word alignment may
1635: cause trouble, but, like $f77$,
1636: it makes no attempt to circumvent this trouble;
1637: the run-time costs of circumvention would be substantial.
1638: .PP
1639: Long decimal strings in \f(CWdata\fP statements are passed to C unaltered.
1640: However, expressions involving long decimal strings are rounded
1641: in a machine-dependent manner.
1642: On a VAX 8550, the Fortran
1643: .P1
1644: x=1.2**10
1645: end
1646: .P2
1647: yields the C
1648: .P1
1649: static real x;
1650:
1651: x = (float)6.1917364224000008;
1652: .P2
1653: .PP
1654: ANSI C compilers require that all but one instance of any entity with external scope,
1655: such as the \f(CWstruct\fPs into which $f2c$ translates \f(CWcommon\fP,
1656: be declared \f(CWextern\fP and that exactly one declaration should define the entity,
1657: i.e., should not be declared \f(CWextern\fP.
1658: Most older C compilers have no such restriction.
1659: To be compatible with ANSI usage, the $f2c$
1660: command-line option
1661: .CW -ec
1662: causes the \f(CWstruct\fP corresponding
1663: to an uninitialized \f(CWcommon\fP region to be declared \f(CWextern\fP
1664: and makes a
1665: .CW union
1666: of all successive declarations of that
1667: \f(CWcommon\fP region into a defining declaration placed in a file with the
1668: name \f(CWcname_com.c\fR, where
1669: .CW cname
1670: is the name of the \f(CWcommon\fP region.
1671: For example, the Fortran
1672: .P1
1673: common /cmname/ c
1674: complex c(10)
1675: c(1)=cmplx(1.,0.)
1676: call sam(c)
1677: end
1678: subroutine sam(c)
1679: complex c
1680: common /cmname/ca
1681: complex ca(10)
1682: ca(2) = cmplx(1e0,2e0)
1683: return
1684: end
1685: .P2
1686: when converted by \f(CWf2c -ec\fP produces
1687: .P1
1688: /* Common Block Declarations */
1689:
1690: union {
1691: struct {
1692: complex c[10];
1693: } _1;
1694: struct {
1695: complex ca[10];
1696: } _2;
1697: } cmname_;
1698:
1699: #define cmname_1 (cmname_._1)
1700: #define cmname_2 (cmname_._2)
1701:
1702: /* Main program */ MAIN_\|\^_()
1703: {
1704:
1705: extern /* Subroutine */ int sam_();
1706:
1707: cmname_1.c[0].r = (float)1., cmname_1.c[0].i = (float)0.;
1708: sam_(cmname_1.c);
1709: } /* MAIN_\|\^_ */
1710:
1711: /* Subroutine */ int sam_(c)
1712: complex *c;
1713: {
1714: cmname_2.ca[1].r = (float)1., cmname_2.ca[1].i = (float)2.;
1715: return 0;
1716: } /* sam_ */
1717: .P2
1718: as well as the file
1719: .CW cmname_com.c :
1720: .P1
1721: #include "f2c.h"
1722: union {
1723: struct {
1724: complex c[10];
1725: } _1;
1726: struct {
1727: complex ca[10];
1728: } _2;
1729: } cmname_;
1730: .P2
1731: The files
1732: .CW *_com.c
1733: may be compiled into a library
1734: against which one can load to satisfy overly fastidious ANSI C compilers.
1735: .PP
1736: The rules of Fortran 77 apparently permit a situation in which
1737: $f2c$ declares a function to be of type
1738: .CW int ,
1739: then defines it to be of another type, as illustrated by the
1740: first example in \(sc7. In that example, $f2c$ discovers too late that
1741: .CW f
1742: is not a subroutine. With some C compilers, this causes nothing
1743: worse than a warning message; with others, it causes the compilation
1744: to be aborted. With unforgiving C compilers, one can usually avoid
1745: trouble by splitting the Fortran source into one file per
1746: procedure, e.g., with the
1747: .I fsplit (1)
1748: command, and converting each procedure separately.
1749: Another solution is to use prototypes, as discussed in \(sc7.
1750: .PP
1751: With an ANSI C system that enforced consistent
1752: prototype declarations across separate compilations,
1753: it would be impossible to translate the main program correctly
1754: in the last example just by looking at the main program.
1755: Recent C++ compilers do enforce the consistency of
1756: prototype declarations across separate compilations,
1757: e.g., by encoding calling sequences into the translated names of functions,
1758: except for functions that are declared \f(CWextern "C"\fR and
1759: compiled separately.
1760: $F2c$ allows one to use this escape hatch: under
1761: .CW -C++ ,
1762: $f2c$ inserts
1763: .P1
1764: #ifdef _\|\^_cplusplus
1765: extern "C" {
1766: #endif
1767: .P2
1768: at the beginning of its C++ output and places
1769: .P1
1770: #ifdef _\|\^_cplusplus
1771: }
1772: #endif
1773: .P2
1774: at the end of its C++ output. The
1775: .CW "#ifdef _\|\^_cplusplus"
1776: lines are for the benefit of older C++ compilers that
1777: do not recognize \f(CWextern "C"\fR.
1778: .SH
1779: 7. PROTOTYPES
1780: .PP
1781: In ANSI C and C++, a
1782: .I prototype
1783: describes the calling sequence of a function.
1784: Prototypes can save debugging time by helping catch
1785: errors in calling sequences. The
1786: .CW \%-P
1787: option instructs $f2c$ to emit prototypes for all
1788: the functions defined in the C it produces; specifically,
1789: $f2c$ creates a \fIfile\f(CW.P\fR of prototypes
1790: for each input \fIfile\f(CW.f\fR or \fIfile\f(CW.F\fR.
1791: One can then arrange for relevant prototype files
1792: to be seen by the C compiler.
1793: For instance, if $f2c$'s
1794: header file
1795: .CW f2c.h
1796: is installed as
1797: .CW /usr/include/f2c.h ,
1798: one could issue the UNIX command
1799: .P1
1800: cat /usr/include/f2c.h *.P >f2c.h
1801: .P2
1802: to create a local copy of
1803: .CW f2c.h
1804: that has in it all the prototypes in
1805: .CW *.P .
1806: Since the C produced by $f2c$ always specifies
1807: .P1
1808: #include "f2c.h"
1809: .P2
1810: (rather than
1811: .CW "#include <f2c.h>" ),
1812: the C compiler will look first in the current directory for
1813: .CW f2c.h
1814: and thus will find the local copy that contains the prototypes.
1815: .PP
1816: $F2c$ can also read the prototype files it writes;
1817: one simply specifies them as arguments to $f2c$.
1818: In fact, $f2c$ reads all prototype files before any
1819: Fortran files; although multiple Fortran files are handled
1820: independently, any prototype file arguments apply to all of them.
1821: $F2c$ has more detailed knowledge of Fortran types than it conveys
1822: in the C it puts out; for example,
1823: .CW logical
1824: and
1825: .CW integer
1826: are different Fortran types, but are mapped to the same C type.
1827: Moreover,
1828: .CW character ,
1829: .CW complex ,
1830: and
1831: .CW "double complex"
1832: Fortran functions are all translated to
1833: .CW VOID
1834: C functions, and, unless the
1835: .CW \%-R
1836: option is specified, both
1837: .CW real
1838: and
1839: .CW "double precision"
1840: Fortran functions are translated to
1841: .CW doublereal
1842: C functions. Because $f2c$ denotes all these
1843: types differently in its prototype files, it
1844: can catch errors that are invisible to an ANSI C
1845: (or C++) compiler.
1846: .PP
1847: The following table shows the types
1848: that $f2c$ uses for procedure arguments:
1849: .TS
1850: center box;
1851: lfCW lfCW.
1852: C_fp complex
1853: D_fp doublereal
1854: E_fp real\fR under \f(CW-!R\fR (the default)\fP
1855: H_fp character
1856: I_fp integer\fR or \f(CWinteger*4
1857: J_fp integer*2
1858: K_fp shortlogical\fR (\f(CWlogical\fR under \f(CW-i2\fR or \f(CW-I2\fR)\fP
1859: L_fp logical
1860: R_fp real\fR under \f(CW-R
1861: S_fp subroutine\fR
1862: U_fp \fRuntyped \f(CWexternal
1863: Z_fp doublecomplex
1864: .TE
1865: These types are defined in
1866: .CW f2c.h ;
1867: they appear in prototypes and, under
1868: .CW \%-A
1869: or
1870: .CW \%-C++ ,
1871: in the C that $f2c$ writes. Prototypes also use special
1872: .CW void
1873: types to denote the return values of
1874: .CW complex ,
1875: .CW "double complex",
1876: and
1877: .CW character
1878: functions:
1879: .TS
1880: center box;
1881: lfCW lfCW.
1882: C_f complex
1883: H_f character
1884: Z_f double complex
1885: .TE
1886: .PP
1887: $F2c$ also writes special comments in prototype files giving
1888: the length of each
1889: .CW common
1890: block; when given prototype files as arguments, $f2c$ reads
1891: these special comments so it can issue a warning message if its
1892: Fortran input specifies a different length for some
1893: .CW common
1894: block.
1895: .PP
1896: Sometimes people write otherwise valid Fortran 77 that
1897: specifies different lengths for a
1898: .CW common
1899: block. If such Fortran is split into several files and converted
1900: to C, the loader could end up giving too little space to the
1901: .CW common
1902: block in question. One can avoid the confusion this could cause by
1903: running $f2c$ twice, first with
1904: .CW \%-P!c ,
1905: then with the resulting prototypes as additional arguments;
1906: the prototypes let $f2c$ determine (and convey to all of its
1907: output C files) the true length needed for
1908: each
1909: .CW common
1910: block.
1911: .PP
1912: One complication with prototypes comes from Fortran subprograms that
1913: declare a procedure to be
1914: .CW external
1915: but do not explicitly specify a type for it and only
1916: pass it as a parameter to another procedure. (If the
1917: subprogram also invokes the
1918: .CW external
1919: procedure, then $f2c$ can tell whether the procedure is
1920: a subroutine or a function; in the latter case, Fortran's
1921: implicit typing rules specify a type for the procedure.)
1922: If it can do no better, then $f2c$ assumes that untyped
1923: .CW external
1924: procedures are subroutines (and hence become
1925: .CW int -valued
1926: functions in C).
1927: This can cause the generated C to have
1928: multiple and inconsistent declarations for some procedures.
1929: For example,
1930: .P1
1931: external f
1932: call foo(f)
1933: end
1934: function f(x)
1935: double precision f, x
1936: f = x
1937: end
1938: .P2
1939: results in
1940: .CW MAIN_\|\^_
1941: declaring
1942: .P1
1943: extern /* Subroutine */ int f_();
1944: .P2
1945: and in the subsequent definition of
1946: .CW "doublereal f_(x)"
1947: in the same C file.
1948: Such inconsistencies are grounds for some C compilers
1949: to abort compilation.
1950: .PP
1951: $F2c$'s type inferences only apply sequentially to
1952: the procedures in a file, because $f2c$ writes C for each procedure
1953: before reading the next one. Thus, as just illustrated, if procedure
1954: .CW xyz
1955: comes after
1956: .CW abc
1957: in a Fortran input file, then $f2c$ cannot use information
1958: it gains when it sees the definition of
1959: .CW xyz
1960: to deduce types for
1961: .CW external
1962: procedures passed as arguments to
1963: .CW xyz
1964: by
1965: .CW abc .
1966: By using the
1967: .CW \%-P
1968: option and running $f2c$ several times, one can
1969: get around this deficiency. For instance, if file
1970: .CW zap.f
1971: contains the Fortran shown above, then the commands
1972: .P1
1973: f2c -P!c zap.f
1974: f2c -A zap.[fP]
1975: .P2
1976: result in a file
1977: .CW zap.c
1978: in which
1979: .CW MAIN_\|\^_
1980: correctly types
1981: .CW f_
1982: and
1983: .CW foo_
1984: as
1985: .P1
1986: extern doublereal f_();
1987: extern /* Subroutine */ int foo_(D_fp);
1988: .P2
1989: rather than
1990: .P1
1991: extern /* Subroutine */ int f_();
1992: extern /* Subroutine */ int foo_(U_fp);
1993: .P2
1994: The first invocation of $f2c$ results in a file
1995: .CW zap.P
1996: containing
1997: .P1
1998: extern doublereal f_(doublereal *x);
1999: /*:ref: foo_ 10 1 200 */
2000: .P2
2001: The second invocation of $f2c$ is able to type
2002: .CW f_
2003: and
2004: .CW foo_
2005: correctly because of the first line in
2006: .CW zap.P .
2007: .PP
2008: The second line in
2009: .CW zap.P
2010: is a special comment that records the incomplete type
2011: information that $f2c$ has about
2012: .CW foo_ .
2013: $F2c$ puts one such special comment in the prototype file for each
2014: Fortran procedure that is referenced but not defined in the Fortran file.
2015: When it reads prototype files, $f2c$ deciphers these comments and
2016: uses them to check the consistency of calling sequences.
2017: As it learns more about untyped external procedures, $f2c$ updates
2018: the information it has on them; the
2019: .CW :ref:
2020: comments it writes in a prototype file reflect $f2c$'s latest knowledge.
2021: .PP
2022: Ordinarily $f2c$ tries to infer the type of an untyped
2023: .CW external
2024: procedure from its use as arguments to procedures of
2025: known argument types. For example, if
2026: .CW f.f
2027: contains just
2028: .P1
2029: external f
2030: call foo(f)
2031: end
2032: .P2
2033: and if
2034: .CW foo.P
2035: contains
2036: .P1
2037: extern int foo_(D_fp);
2038: .P2
2039: then
2040: .P1
2041: f2c -A f.f foo.P
2042: .P2
2043: results in the declaration
2044: .P1
2045: extern doublereal f_();
2046: .P2
2047: Under unusual circumstances, such type inferences
2048: can lead to erroneous error messages or to incorrect typing.
2049: Here is an example:
2050: .P1
2051: subroutine zoo
2052: external f
2053: double precision f
2054: external g
2055: call zap(1,f)
2056: call zap(2,g)
2057: end
2058: subroutine goo
2059: call g
2060: end
2061: .P2
2062: $F2c$ first infers g to be a double precision function, then discovers
2063: that it must be a subroutine and issues a warning message about
2064: inconsistent declarations for
2065: .CW g .
2066: This example is legal Fortran 77;
2067: .CW zap
2068: could be defined, for instance, by
2069: .P1
2070: subroutine zap(n,f)
2071: external f
2072: if (n .le. 1) call zap1(f)
2073: if (n .ge. 2) call zap2(f)
2074: end
2075: .P2
2076: In such a case one can specify the
2077: .CW \%-!it
2078: option to instruct $f2c$ not to infer the types of otherwise
2079: untypable
2080: .CW external
2081: procedures from their appearance as arguments to known procedures.
2082: Here is another (somewhat far-fetched) example where
2083: .CW \%-!it
2084: is useful:
2085: .P1
2086: subroutine grok(f,g,h)
2087: external f, g, h
2088: logical g
2089: call foo(1,g)
2090: call foo(2,f)
2091: call zit(1,f)
2092: call zit(2,h)
2093: call zot(f(3))
2094: end
2095: .P2
2096: Without
2097: .CW \%-!it ,
2098: $f2c$ first infers
2099: .CW f_
2100: to be a
2101: .CW logical
2102: function, then discovers that Fortran's implicit typing
2103: rules require it to be a
2104: .CW real
2105: function.
2106: $F2c$ issues the
2107: warning message
2108: .CW "fixing wrong type inferred for f" '', ``
2109: which should serve as a warning that $f2c$ may have made some
2110: incorrect type inferences in the mean time.
2111: Indeed, $f2c$ ends up typing
2112: .CW h_
2113: as a
2114: .CW logical
2115: function; with
2116: .CW \%-!it
2117: specified, $f2c$ types
2118: .CW h_
2119: as an
2120: .CW external
2121: procedure unknown type, i.e., a
2122: .CW U_fp ,
2123: which to the C compiler appears to be a subroutine.
2124: (Even with
2125: .CW \%-!it
2126: specified, $f2c$ issues a warning message about inconsistent
2127: calling sequences for
2128: .CW foo .)
2129: .PP
2130: Because $f2c$ writes its latest knowledge of types into
2131: prototype files, it is easy to write a crude (Bourne) shell script
2132: that will glean the maximum possible type information:
2133: .P1
2134: >f.p
2135: until
2136: f2c -Pit f.p f.f
2137: cmp -s f.p f.P
2138: do
2139: mv f.P f.p
2140: done
2141: .P2
2142: In such scripts, use of the
2143: .CW \%-Ps
2144: option can save an iteration;
2145: .CW \%-Ps
2146: implies
2147: .CW \%-P
2148: and instructs $f2c$ to issue return code 4 if another
2149: iteration might change a declaration or prototype.
2150: Thus the following script is more efficient:
2151: .EQ
2152: delim off
2153: .EN
2154: .P1
2155: while :; do
2156: f2c -Ps f.[fP]
2157: case $? in 4) ;; *) break;; esac
2158: done
2159: .P2
2160: .EQ
2161: delim $$
2162: .EN
2163: The number of iterations depends on the call graph of the
2164: procedures in
2165: .CW f.f
2166: and on their order of appearance in
2167: .CW f.f .
2168: Sorting them into topological order (so that if
2169: .CW abc
2170: calls
2171: .CW def ,
2172: then
2173: .CW abc
2174: precedes
2175: .CW def )
2176: and reverse topological order and alternating between
2177: the two orders
2178: is probably a good heuristic.
2179: For example, we were able to completely type
2180: the \s-2PORT3\s+2 subroutine library
2181: in two passes by first processing it in reverse topological order,
2182: then in forward order. Unfortunately, one can devise situations
2183: where arbitrarily many iterations are required. This is slightly
2184: annoying, since with appropriate data structures (in an extensively
2185: reorganized version of $f2c$), one could do this calculation
2186: in linear time.
2187: .SH
2188: 8. EXPERIENCE WITH \f(BInetlib\fP
2189: .PP
2190: With the help of Eric Grosse, we arranged for the $netlib$
2191: .[ [
2192: Dongarra Grosse 1987
2193: .]]
2194: server
2195: .CW [email protected]
2196: to provide an experimental Fortran-to-C translation service
2197: by electronic mail.
2198: By executing the UNIX command
2199: .sp .5
2200: .ce
2201: \f(CW(echo execute f2c; cat foo.f) | mail [email protected]\fR
2202: .sp .5
2203: one submits the Fortran in
2204: .CW foo.f
2205: to $netlib$'s $f2c$ service;
2206: $netlib$ replies with the C and diagnostic messages produced by $f2c$ from
2207: .CW foo.f .
2208: (The
2209: .CW include
2210: mechanism described in \(sc3 makes no sense in this
2211: context, so it is disabled.) To start using this service,
2212: one would generally execute
2213: .sp .5
2214: .ce
2215: \f(CWecho 'send index from f2c' | mail [email protected]\fR
2216: .sp .5
2217: to check on the current status of the service.
2218: Before compiling the returned C, it is necessary to get a copy of
2219: .CW f2c.h :
2220: .sp .5
2221: .ce
2222: \f(CWecho 'send f2c.h from f2c' | mail [email protected]\fR
2223: .sp .5
2224: Most likely it would also be necessary to obtain source for the
2225: versions of $libF77$ and $libI77$ assumed by $f2c$:
2226: .sp .5
2227: .ce
2228: \f(CWecho 'send libf77 libi77 from f2c' | mail [email protected]\fR
2229: .PP
2230: For testing purposes, we retain the original Fortran submitted to
2231: $netlib$'s
2232: .CW "execute f2c" '' ``
2233: service. Observing $f2c$'s behavior on over 400,000 lines
2234: of submitted Fortran helped
2235: us find many obscure bugs and led us to make some of the
2236: extensions described in \(sc3. For example, a
2237: .CW "block data"
2238: subprogram initializing a variable that does not appear
2239: in any
2240: .CW common
2241: blocks now elicits a warning message (rather than causing
2242: $f2c$ to drop core). Another example is that $f2c$
2243: now gives the warning message
2244: .CW "Statement order error: declaration after DATA" '' ``
2245: and declines to produce any C
2246: if a declaration comes after a
2247: .CW data
2248: statement (for reasons discussed in \(sc9);
2249: $f2c$ formerly gave a more obscure error message
2250: and then produced invalid C.
2251: .PP
2252: Now that $netlib$ offers source for $f2c$ itself (as explained
2253: in the
2254: .CW index
2255: file mentioned above), we expect to curtail $netlib$'s
2256: .CW "execute f2c" '' ``
2257: service, perhaps limiting it to employees of AT&T and Bellcore;
2258: to learn the current state of affairs, request the current
2259: .CW index
2260: file.
2261: .SH
2262: 9. POSSIBLE EXTENSIONS
2263: .PP
2264: Currently $f2c$ simplifies constant expressions.
2265: It would be nice if constant expressions were simply
2266: passed through, and if Fortran
2267: .CW parameter s
2268: were translated as
2269: .CW #define s.
2270: Unfortunately, several things conspire to make this
2271: nearly impossible to do in full generality.
2272: Perhaps worst is that
2273: .CW parameter s
2274: may be assigned
2275: .CW complex
2276: or
2277: .CW doublecomplex
2278: expressions that might, for example, involve complex division
2279: and exponentiation to a large integer power.
2280: .CW Parameter s
2281: may appear in
2282: .CW data
2283: statements, which may initialize
2284: .CW common
2285: variables and so be moved near the beginning of the C output.
2286: Arranging to have the right
2287: .CW #define s
2288: in effect for the data initialization would, in this worst case,
2289: be a nightmare. Of course, one could arrange to
2290: handle ``easy'' cases with unsimplified constant expressions
2291: and
2292: .CW #define s
2293: for parameters.
2294: .PP
2295: Prototypes and the argument consistency checks currently ignore
2296: alternate return specifiers. Prototypes could be adorned with
2297: special comments indicating where alternate return specifiers
2298: are supposed to come, or at least telling the number of such
2299: specifiers, which is all that really matters.
2300: Since alternate return specifiers are rarely used
2301: (Fortran 90 calls them ``obsolescent''),
2302: we have so far refrained from this exercise.
2303: .PP
2304: Fortran 90 allows
2305: .CW data
2306: statements to appear anywhere. It would be nice if $f2c$ could
2307: do the same, but that would entail major rewriting of $f2c$.
2308: Presently
2309: .CW data
2310: values are written to a file as soon as they are seen; among
2311: the information in the file is the offset of each value.
2312: If an
2313: .CW equivalence
2314: statement could follow the
2315: .CW data
2316: statement, then the offsets would be invalidated.
2317: .PP
2318: It would be fairly straightforward to extend $f2c$'s I/O
2319: to encompass the new specifiers introduced by Fortran 90.
2320: Unfortunately, that would mean changing $libI77$ in ways
2321: that would make it incompatible with $f77$.
2322: .PP
2323: Of course, it would be nice to translate all of Fortran 90, but
2324: some of the Fortran 90 array manipulations would require new
2325: calling conventions and large enough revisions to $f2c$ that
2326: one might be better off starting from scratch.
2327: .PP
2328: With sufficient hacking,
2329: $f2c$ could be modified to recognize
2330: Fortran 90 control structures
2331: .CW case , (
2332: .CW cycle ,
2333: .CW exit ,
2334: and named loops), local arrays of
2335: dimensions that depend on arguments and common values,
2336: and such types as
2337: .CW logical*1 ,
2338: .CW logical*2 ,
2339: .CW integer*1
2340: or
2341: .CW byte .
2342: Since our main concern is with making portable Fortran 77
2343: libraries available to the C world, we have so far refrained
2344: from these further extensions. Perhaps commercial
2345: vendors will wish to provide some of these extensions.
2346: .SH
2347: 10. REFERENCES
2348: .LP
2349: .so tmac.sdisp1
2350: .[
2351: $LIST$
2352: .]
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.