Annotation of researchv10no/cmd/f2c/doc/proto, revision 1.1

1.1     ! root        1: .SH
        !             2: 7. PROTOTYPES
        !             3: .PP
        !             4: In ANSI C and C++, a
        !             5: .I prototype
        !             6: describes the calling sequence of a function.
        !             7: Prototypes can save debugging time by helping catch
        !             8: errors in calling sequences.  The
        !             9: .CW \%-P
        !            10: option instructs $f2c$ to emit prototypes for all
        !            11: the functions defined in the C it produces; specifically,
        !            12: $f2c$ creates a \fIfile\f(CW.P\fR of prototypes
        !            13: for each input \fIfile\f(CW.f\fR or \fIfile\f(CW.F\fR.
        !            14: One can then arrange for relevant prototype files
        !            15: to be seen by the C compiler.
        !            16: For instance, if $f2c$'s
        !            17: header file
        !            18: .CW f2c.h
        !            19: is installed as
        !            20: .CW /usr/include/f2c.h ,
        !            21: one could issue the UNIX command
        !            22: .P1
        !            23: cat /usr/include/f2c.h *.P >f2c.h
        !            24: .P2
        !            25: to create a local copy of
        !            26: .CW f2c.h
        !            27: that has in it all the prototypes in
        !            28: .CW *.P .
        !            29: Since the C produced by $f2c$ always specifies
        !            30: .P1
        !            31: #include "f2c.h"
        !            32: .P2
        !            33: (rather than
        !            34: .CW "#include <f2c.h>" ),
        !            35: the C compiler will look first in the current directory for
        !            36: .CW f2c.h
        !            37: and thus will find the local copy that contains the prototypes.
        !            38: .PP
        !            39: $F2c$ can also read the prototype files it writes;
        !            40: one simply specifies them as arguments to $f2c$.
        !            41: In fact, $f2c$ reads all prototype files before any
        !            42: Fortran files; although multiple Fortran files are handled
        !            43: independently, any prototype file arguments apply to all of them.
        !            44: $F2c$ has more detailed knowledge of Fortran types than it conveys
        !            45: in the C it puts out; for example,
        !            46: .CW logical
        !            47: and
        !            48: .CW integer
        !            49: are different Fortran types, but are mapped to the same C type.
        !            50: Moreover,
        !            51: .CW character ,
        !            52: .CW complex ,
        !            53: and
        !            54: .CW "double complex"
        !            55: Fortran functions are all translated to
        !            56: .CW VOID
        !            57: C functions, and, unless the
        !            58: .CW \%-R
        !            59: option is specified, both
        !            60: .CW real
        !            61: and
        !            62: .CW "double precision"
        !            63: Fortran functions are translated to
        !            64: .CW doublereal
        !            65: C functions.  Because $f2c$ denotes all these
        !            66: types differently in its prototype files, it
        !            67: can catch errors that are invisible to an ANSI C
        !            68: (or C++) compiler.
        !            69: .PP
        !            70: The following table shows the types
        !            71: that $f2c$ uses for procedure arguments:
        !            72: .TS
        !            73: center box;
        !            74: lfCW lfCW.
        !            75: C_fp   complex
        !            76: D_fp   doublereal
        !            77: E_fp   real\fR under \f(CW-!R\fR (the default)\fP
        !            78: H_fp   character
        !            79: I_fp   integer\fR or \f(CWinteger*4
        !            80: J_fp   integer*2
        !            81: K_fp   shortlogical\fR (\f(CWlogical\fR under \f(CW-i2\fR or \f(CW-I2\fR)\fP
        !            82: L_fp   logical
        !            83: R_fp   real\fR under \f(CW-R
        !            84: S_fp   subroutine\fR
        !            85: U_fp   \fRuntyped \f(CWexternal
        !            86: Z_fp   doublecomplex
        !            87: .TE
        !            88: These types are defined in
        !            89: .CW f2c.h ;
        !            90: they appear in prototypes and, under
        !            91: .CW \%-A
        !            92: or
        !            93: .CW \%-C++ ,
        !            94: in the C that $f2c$ writes.  Prototypes also use special
        !            95: .CW void
        !            96: types to denote the return values of
        !            97: .CW complex ,
        !            98: .CW "double complex",
        !            99: and
        !           100: .CW character
        !           101: functions:
        !           102: .TS
        !           103: center box;
        !           104: lfCW lfCW.
        !           105: C_f    complex
        !           106: H_f    character
        !           107: Z_f    double complex
        !           108: .TE
        !           109: .PP
        !           110: $F2c$ also writes special comments in prototype files giving
        !           111: the length of each
        !           112: .CW common
        !           113: block; when given prototype files as arguments, $f2c$ reads
        !           114: these special comments so it can issue a warning message if its
        !           115: Fortran input specifies a different length for some
        !           116: .CW common
        !           117: block.
        !           118: .PP
        !           119: Sometimes people write otherwise valid Fortran 77 that
        !           120: specifies different lengths for a
        !           121: .CW common
        !           122: block.  If such Fortran is split into several files and converted
        !           123: to C, the loader could end up giving too little space to the
        !           124: .CW common
        !           125: block in question.  One can avoid the confusion this could cause by
        !           126: running $f2c$ twice, first with
        !           127: .CW \%-P!c ,
        !           128: then with the resulting prototypes as additional arguments;
        !           129: the prototypes let $f2c$ determine (and convey to all of its
        !           130: output C files) the true length needed for
        !           131: each
        !           132: .CW common
        !           133: block.
        !           134: .PP
        !           135: One complication with prototypes comes from Fortran subprograms that
        !           136: declare a procedure to be
        !           137: .CW external
        !           138: but do not explicitly specify a type for it and only
        !           139: pass it as a parameter to another procedure.  (If the
        !           140: subprogram also invokes the
        !           141: .CW external
        !           142: procedure, then $f2c$ can tell whether the procedure is
        !           143: a subroutine or a function; in the latter case, Fortran's
        !           144: implicit typing rules specify a type for the procedure.)
        !           145: If it can do no better, then $f2c$ assumes that untyped
        !           146: .CW external
        !           147: procedures are subroutines (and hence become
        !           148: .CW int -valued
        !           149: functions in C).
        !           150: This can cause the generated C to have
        !           151: multiple and inconsistent declarations for some procedures.
        !           152: For example,
        !           153: .P1
        !           154:        external f
        !           155:        call foo(f)
        !           156:        end
        !           157:        function f(x)
        !           158:        double precision f, x
        !           159:        f = x
        !           160:        end
        !           161: .P2
        !           162: results in
        !           163: .CW MAIN_\|_
        !           164: declaring
        !           165: .P1
        !           166:     extern /* Subroutine */ int f_();
        !           167: .P2
        !           168: and in the subsequent definition of
        !           169: .CW "doublereal f_(x)"
        !           170: in the same C file.
        !           171: Such inconsistencies are grounds for some C compilers
        !           172: to abort compilation.
        !           173: .PP
        !           174: $F2c$'s type inferences only apply sequentially to
        !           175: the procedures in a file, because $f2c$ writes C for each procedure
        !           176: before reading the next one.  Thus, as just illustrated, if procedure
        !           177: .CW xyz
        !           178: comes after
        !           179: .CW abc
        !           180: in a Fortran input file, then $f2c$ cannot use information
        !           181: it gains when it sees the definition of
        !           182: .CW xyz
        !           183: to deduce types for
        !           184: .CW external
        !           185: procedures passed as arguments to
        !           186: .CW xyz
        !           187: by
        !           188: .CW abc .
        !           189: By using the
        !           190: .CW \%-P
        !           191: option and running $f2c$ several times, one can
        !           192: get around this deficiency.  For instance, if file
        !           193: .CW zap.f
        !           194: contains the Fortran shown above, then the commands
        !           195: .P1
        !           196:        f2c -P!c zap.f
        !           197:        f2c -A zap.[fP]
        !           198: .P2
        !           199: result in a file
        !           200: .CW zap.c
        !           201: in which
        !           202: .CW MAIN_\|_
        !           203: correctly types
        !           204: .CW f_
        !           205: and
        !           206: .CW foo_
        !           207: as
        !           208: .P1
        !           209:     extern doublereal f_();
        !           210:     extern /* Subroutine */ int foo_(D_fp);
        !           211: .P2
        !           212: rather than
        !           213: .P1
        !           214:     extern /* Subroutine */ int f_();
        !           215:     extern /* Subroutine */ int foo_(U_fp);
        !           216: .P2
        !           217: The first invocation of $f2c$ results in a file
        !           218: .CW zap.P
        !           219: containing
        !           220: .P1
        !           221: extern doublereal f_(doublereal *x);
        !           222: /*:ref: foo_ 10 1 200 */
        !           223: .P2
        !           224: The second invocation of $f2c$ is able to type
        !           225: .CW f_
        !           226: and
        !           227: .CW foo_
        !           228: correctly because of the first line in
        !           229: .CW zap.P .
        !           230: .PP
        !           231: The second line in
        !           232: .CW zap.P
        !           233: is a special comment that records the incomplete type
        !           234: information that $f2c$ has about
        !           235: .CW foo_ .
        !           236: $F2c$ puts one such special comment in the prototype file for each
        !           237: Fortran procedure that is referenced but not defined in the Fortran file.
        !           238: When it reads prototype files, $f2c$ deciphers these comments and
        !           239: uses them to check the consistency of calling sequences.
        !           240: As it learns more about untyped external procedures, $f2c$ updates
        !           241: the information it has on them; the
        !           242: .CW :ref:
        !           243: comments it writes in a prototype file reflect $f2c$'s latest knowledge.
        !           244: .PP
        !           245: Ordinarily $f2c$ tries to infer the type of an untyped
        !           246: .CW external
        !           247: procedure from its use as arguments to procedures of
        !           248: known argument types.  For example, if
        !           249: .CW f.f
        !           250: contains just
        !           251: .P1
        !           252:        external f
        !           253:        call foo(f)
        !           254:        end
        !           255: .P2
        !           256: and if
        !           257: .CW foo.P
        !           258: contains
        !           259: .P1
        !           260: extern int foo_(D_fp);
        !           261: .P2
        !           262: then
        !           263: .P1
        !           264: f2c -A f.f foo.P
        !           265: .P2
        !           266: results in the declaration
        !           267: .P1
        !           268:     extern doublereal f_();
        !           269: .P2
        !           270: Under unusual circumstances, such type inferences
        !           271: can lead to erroneous error messages or to incorrect typing.
        !           272: Here is an example:
        !           273: .P1
        !           274:        subroutine zoo
        !           275:        external f
        !           276:        double precision f
        !           277:        external g
        !           278:        call zap(1,f)
        !           279:        call zap(2,g)
        !           280:        end
        !           281:        subroutine goo
        !           282:        call g
        !           283:        end
        !           284: .P2
        !           285: $F2c$ first infers g to be a double precision function, then discovers
        !           286: that it must be a subroutine and issues a warning message about
        !           287: inconsistent declarations for
        !           288: .CW g .
        !           289: This example is legal Fortran 77;
        !           290: .CW zap
        !           291: could be defined, for instance, by
        !           292: .P1
        !           293:        subroutine zap(n,f)
        !           294:        external f
        !           295:        if (n .le. 1) call zap1(f)
        !           296:        if (n .ge. 2) call zap2(f)
        !           297:        end
        !           298: .P2
        !           299: In such a case one can specify the
        !           300: .CW \%-!it
        !           301: option to instruct $f2c$ not to infer the types of otherwise
        !           302: untypable
        !           303: .CW external
        !           304: procedures from their appearance as arguments to known procedures.
        !           305: Here is another (somewhat far-fetched) example where
        !           306: .CW \%-!it
        !           307: is useful:
        !           308: .P1
        !           309:        subroutine grok(f,g,h)
        !           310:        external f, g, h
        !           311:        logical g
        !           312:        call foo(1,g)
        !           313:        call foo(2,f)
        !           314:        call zit(1,f)
        !           315:        call zit(2,h)
        !           316:        call zot(f(3))
        !           317:        end
        !           318: .P2
        !           319: Without
        !           320: .CW \%-!it ,
        !           321: $f2c$ first infers
        !           322: .CW f_
        !           323: to be a
        !           324: .CW logical
        !           325: function, then discovers that Fortran's implicit typing
        !           326: rules require it to be a
        !           327: .CW real
        !           328: function.
        !           329: $F2c$ issues the
        !           330: warning message
        !           331: .CW "fixing wrong type inferred for f" '', ``
        !           332: which should serve as a warning that $f2c$ may have made some
        !           333: incorrect type inferences in the mean time.
        !           334: Indeed, $f2c$ ends up typing
        !           335: .CW h_
        !           336: as a
        !           337: .CW logical
        !           338: function; with
        !           339: .CW \%-!it
        !           340: specified, $f2c$ types
        !           341: .CW h_
        !           342: as an
        !           343: .CW external
        !           344: procedure unknown type, i.e., a
        !           345: .CW U_fp ,
        !           346: which to the C compiler appears to be a subroutine.
        !           347: (Even with
        !           348: .CW \%-!it
        !           349: specified, $f2c$ issues a warning message about inconsistent
        !           350: calling sequences for
        !           351: .CW foo .)
        !           352: .PP
        !           353: Because $f2c$ writes its latest knowledge of types into
        !           354: prototype files, it is easy to write a crude script
        !           355: that will glean the maximum possible type information:
        !           356: .P1
        !           357: >f.p
        !           358: until
        !           359:        f2c -Pit f.p f.f
        !           360:        cmp -s f.p f.P
        !           361: do
        !           362:        mv f.P f.p
        !           363:        done
        !           364: .P2
        !           365: In such scripts, use of the
        !           366: .CW \%-Ps
        !           367: option can save an iteration;
        !           368: .CW \%-Ps
        !           369: implies
        !           370: .CW \%-P
        !           371: and instructs $f2c$ to issue return code 4 if another
        !           372: iteration might change a declaration or prototype.
        !           373: Thus the following script is more efficient:
        !           374: .EQ
        !           375: delim off
        !           376: .EN
        !           377: .P1
        !           378: while :; do
        !           379:        f2c -Ps f.[fP]
        !           380:        case $? in 4) ;; *) break;; esac
        !           381:        done
        !           382: .P2
        !           383: .EQ
        !           384: delim $$
        !           385: .EN
        !           386: The number of iterations depends on the call graph of the
        !           387: procedures in
        !           388: .CW f.f
        !           389: and on their order of appearance in
        !           390: .CW f.f .
        !           391: Sorting them into topological order (so that if
        !           392: .CW abc
        !           393: calls
        !           394: .CW def ,
        !           395: then
        !           396: .CW abc
        !           397: precedes
        !           398: .CW def )
        !           399: and reverse topological order and alternating between
        !           400: the two orders
        !           401: is probably a good heuristic.
        !           402: For example, we were able to completely type
        !           403: the \s-2PORT3\s+2 subroutine library
        !           404: in two passes by first processing it in reverse topological order,
        !           405: then in forward order.  Unfortunately, one can devise situations
        !           406: where arbitrarily many iterations are required.  This is slightly
        !           407: annoying, since with appropriate data structures (in an extensively
        !           408: reorganized version of $f2c$), one could do this calculation
        !           409: in linear time.

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.