This is g77.info, produced by makeinfo version 4.8 from
/usr/obj/ports/g77-3.3.6/g77/gcc/f/g77.texi.

   Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004 Free
Software Foundation, Inc.

   Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.2 or
any later version published by the Free Software Foundation; with the
Invariant Sections being "GNU General Public License" and "Funding Free
Software", the Front-Cover texts being (a) (see below), and with the
Back-Cover Texts being (b) (see below).  A copy of the license is
included in the section entitled "GNU Free Documentation License".

   (a) The FSF's Front-Cover Text is:

   A GNU Manual

   (b) The FSF's Back-Cover Text is:

   You have freedom to copy and modify this GNU Manual, like GNU
software.  Copies published by the Free Software Foundation raise
funds for GNU development.

INFO-DIR-SECTION Programming
START-INFO-DIR-ENTRY
* g77: (g77).                  The GNU Fortran compiler.
END-INFO-DIR-ENTRY
   This file documents the use and the internals of the GNU Fortran
(`g77') compiler.  It corresponds to the GCC-3.3.6 version of `g77'.

   Published by the Free Software Foundation 59 Temple Place - Suite 330
Boston, MA 02111-1307 USA

   Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004 Free
Software Foundation, Inc.

   Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.2 or
any later version published by the Free Software Foundation; with the
Invariant Sections being "GNU General Public License" and "Funding Free
Software", the Front-Cover texts being (a) (see below), and with the
Back-Cover Texts being (b) (see below).  A copy of the license is
included in the section entitled "GNU Free Documentation License".

   (a) The FSF's Front-Cover Text is:

   A GNU Manual

   (b) The FSF's Back-Cover Text is:

   You have freedom to copy and modify this GNU Manual, like GNU
software.  Copies published by the Free Software Foundation raise
funds for GNU development.

   Contributed by James Craig Burley (<craig@jcb-sc.com>).  Inspired by
a first pass at translating `g77-0.5.16/f/DOC' that was contributed to
Craig by David Ronis (<ronis@onsager.chem.mcgill.ca>).


File: g77.info,  Node: System Intrinsic (function),  Next: TanD Intrinsic,  Prev: SymLnk Intrinsic (function),  Up: Other Intrinsics

10.5.2.132 System Intrinsic (function)
......................................


     System(COMMAND)

System: `INTEGER(KIND=1)' function.

COMMAND: `CHARACTER'; scalar; INTENT(IN).

Intrinsic groups: `badu77'.

Description:

   Passes the command COMMAND to a shell (see `system(3)').  Returns
the value returned by `system(3)', presumably 0 if the shell command
succeeded.  Note that which shell is used to invoke the command is
system-dependent and environment-dependent.

   Due to the side effects performed by this intrinsic, the function
form is not recommended.  However, the function form can be valid in
cases where the actual side effects performed by the call are
unimportant to the application.

   For example, on a UNIX system, `SAME = SYSTEM('cmp a b')' does not
perform any side effects likely to be important to the program, so the
programmer would not care if the actual system call (and invocation of
`cmp') was optimized away in a situation where the return value could
be determined otherwise, or was not actually needed (`SAME' not
actually referenced after the sample assignment statement).

   For information on other intrinsics with the same name: *Note System
Intrinsic (subroutine)::.


File: g77.info,  Node: TanD Intrinsic,  Next: Time Intrinsic (VXT),  Prev: System Intrinsic (function),  Up: Other Intrinsics

10.5.2.133 TanD Intrinsic
.........................

This intrinsic is not yet implemented.  The name is, however, reserved
as an intrinsic.  Use `EXTERNAL TanD' to use this name for an external
procedure.


File: g77.info,  Node: Time Intrinsic (VXT),  Next: UMask Intrinsic (function),  Prev: TanD Intrinsic,  Up: Other Intrinsics

10.5.2.134 Time Intrinsic (VXT)
...............................


     CALL Time(TIME)

TIME: `CHARACTER*8'; scalar; INTENT(OUT).

Intrinsic groups: `vxt'.

Description:

   Returns in TIME a character representation of the current time as
obtained from `ctime(3)'.

   Programs making use of this intrinsic might not be Year 10000 (Y10K)
compliant.  For example, the date might appear, to such programs, to
wrap around (change from a larger value to a smaller one) as of the
Year 10000.

   *Note FDate Intrinsic (subroutine)::, for an equivalent routine.

   For information on other intrinsics with the same name: *Note Time
Intrinsic (UNIX)::.


File: g77.info,  Node: UMask Intrinsic (function),  Next: Unlink Intrinsic (function),  Prev: Time Intrinsic (VXT),  Up: Other Intrinsics

10.5.2.135 UMask Intrinsic (function)
.....................................


     UMask(MASK)

UMask: `INTEGER(KIND=1)' function.

MASK: `INTEGER'; scalar; INTENT(IN).

Intrinsic groups: `badu77'.

Description:

   Sets the file creation mask to MASK and returns the old value.  See
`umask(2)'.

   Due to the side effects performed by this intrinsic, the function
form is not recommended.

   For information on other intrinsics with the same name: *Note UMask
Intrinsic (subroutine)::.


File: g77.info,  Node: Unlink Intrinsic (function),  Next: ZExt Intrinsic,  Prev: UMask Intrinsic (function),  Up: Other Intrinsics

10.5.2.136 Unlink Intrinsic (function)
......................................


     Unlink(FILE)

Unlink: `INTEGER(KIND=1)' function.

FILE: `CHARACTER'; scalar; INTENT(IN).

Intrinsic groups: `badu77'.

Description:

   Unlink the file FILE.  A null character (`CHAR(0)') marks the end of
the name in FILE--otherwise, trailing blanks in FILE are ignored.
Returns 0 on success or a nonzero error code.  See `unlink(2)'.

   Due to the side effects performed by this intrinsic, the function
form is not recommended.

   For information on other intrinsics with the same name: *Note Unlink
Intrinsic (subroutine)::.


File: g77.info,  Node: ZExt Intrinsic,  Prev: Unlink Intrinsic (function),  Up: Other Intrinsics

10.5.2.137 ZExt Intrinsic
.........................

This intrinsic is not yet implemented.  The name is, however, reserved
as an intrinsic.  Use `EXTERNAL ZExt' to use this name for an external
procedure.


File: g77.info,  Node: Other Compilers,  Next: Other Languages,  Prev: Other Dialects,  Up: Top

11 Other Compilers
******************

An individual Fortran source file can be compiled to an object (`*.o')
file instead of to the final program executable.  This allows several
portions of a program to be compiled at different times and linked
together whenever a new version of the program is needed.  However, it
introduces the issue of "object compatibility" across the various
object files (and libraries, or `*.a' files) that are linked together
to produce any particular executable file.

   Object compatibility is an issue when combining, in one program,
Fortran code compiled by more than one compiler (or more than one
configuration of a compiler).  If the compilers disagree on how to
transform the names of procedures, there will normally be errors when
linking such programs.  Worse, if the compilers agree on naming, but
disagree on issues like how to pass parameters, return arguments, and
lay out `COMMON' areas, the earliest detected errors might be the
incorrect results produced by the program (and that assumes these
errors are detected, which is not always the case).

   Normally, `g77' generates code that is object-compatible with code
generated by a version of `f2c' configured (with, for example, `f2c.h'
definitions) to be generally compatible with `g77' as built by `gcc'.
(Normally, `f2c' will, by default, conform to the appropriate
configuration, but it is possible that older or perhaps even newer
versions of `f2c', or versions having certain configuration changes to
`f2c' internals, will produce object files that are incompatible with
`g77'.)

   For example, a Fortran string subroutine argument will become two
arguments on the C side: a `char *' and an `int' length.

   Much of this compatibility results from the fact that `g77' uses the
same run-time library, `libf2c', used by `f2c', though `g77' gives its
version the name `libg2c' so as to avoid conflicts when linking,
installing them in the same directories, and so on.

   Other compilers might or might not generate code that is
object-compatible with `libg2c' and current `g77', and some might offer
such compatibility only when explicitly selected via a command-line
option to the compiler.

   _Note: This portion of the documentation definitely needs a lot of
work!_

* Menu:

* Dropping f2c Compatibility::  When speed is more important.
* Compilers Other Than f2c::    Interoperation with code from other compilers.


File: g77.info,  Node: Dropping f2c Compatibility,  Next: Compilers Other Than f2c,  Up: Other Compilers

11.1 Dropping `f2c' Compatibility
=================================

Specifying `-fno-f2c' allows `g77' to generate, in some cases, faster
code, by not needing to allow to the possibility of linking with code
compiled by `f2c'.

   For example, this affects how `REAL(KIND=1)', `COMPLEX(KIND=1)', and
`COMPLEX(KIND=2)' functions are called.  With `-fno-f2c', they are
compiled as returning the appropriate `gcc' type (`float', `__complex__
float', `__complex__ double', in many configurations).

   With `-ff2c' in force, they are compiled differently (with perhaps
slower run-time performance) to accommodate the restrictions inherent
in `f2c''s use of K&R C as an intermediate language--`REAL(KIND=1)'
functions return C's `double' type, while `COMPLEX' functions return
`void' and use an extra argument pointing to a place for the functions
to return their values.

   It is possible that, in some cases, leaving `-ff2c' in force might
produce faster code than using `-fno-f2c'.  Feel free to experiment,
but remember to experiment with changing the way _entire programs and
their Fortran libraries are compiled_ at a time, since this sort of
experimentation affects the interface of code generated for a Fortran
source file--that is, it affects object compatibility.

   Note that `f2c' compatibility is a fairly static target to achieve,
though not necessarily perfectly so, since, like `g77', it is still
being improved.  However, specifying `-fno-f2c' causes `g77' to
generate code that will probably be incompatible with code generated by
future versions of `g77' when the same option is in force.  You should
make sure you are always able to recompile complete programs from
source code when upgrading to new versions of `g77' or `f2c',
especially when using options such as `-fno-f2c'.

   Therefore, if you are using `g77' to compile libraries and other
object files for possible future use and you don't want to require
recompilation for future use with subsequent versions of `g77', you
might want to stick with `f2c' compatibility for now, and carefully
watch for any announcements about changes to the `f2c'/`libf2c'
interface that might affect existing programs (thus requiring
recompilation).

   It is probable that a future version of `g77' will not, by default,
generate object files compatible with `f2c', and that version probably
would no longer use `libf2c'.  If you expect to depend on this
compatibility in the long term, use the options `-ff2c -ff2c-library'
when compiling all of the applicable code.  This should cause future
versions of `g77' either to produce compatible code (at the expense of
the availability of some features and performance), or at the very
least, to produce diagnostics.

   (The library `g77' produces will no longer be named `libg2c' when it
is no longer generally compatible with `libf2c'.  It will likely be
referred to, and, if installed as a distinct library, named `libg77',
or some other as-yet-unused name.)


File: g77.info,  Node: Compilers Other Than f2c,  Prev: Dropping f2c Compatibility,  Up: Other Compilers

11.2 Compilers Other Than `f2c'
===============================

On systems with Fortran compilers other than `f2c' and `g77', code
compiled by `g77' is not expected to work well with code compiled by
the native compiler.  (This is true for `f2c'-compiled objects as well.)
Libraries compiled with the native compiler probably will have to be
recompiled with `g77' to be used with `g77'-compiled code.

   Reasons for such incompatibilities include:

   * There might be differences in the way names of Fortran procedures
     are translated for use in the system's object-file format.  For
     example, the statement `CALL FOO' might be compiled by `g77' to
     call a procedure the linker `ld' sees given the name `_foo_',
     while the apparently corresponding statement `SUBROUTINE FOO'
     might be compiled by the native compiler to define the
     linker-visible name `_foo', or `_FOO_', and so on.

   * There might be subtle type mismatches which cause subroutine
     arguments and function return values to get corrupted.

     This is why simply getting `g77' to transform procedure names the
     same way a native compiler does is not usually a good idea--unless
     some effort has been made to ensure that, aside from the way the
     two compilers transform procedure names, everything else about the
     way they generate code for procedure interfaces is identical.

   * Native compilers use libraries of private I/O routines which will
     not be available at link time unless you have the native
     compiler--and you would have to explicitly ask for them.

     For example, on the Sun you would have to add `-L/usr/lang/SCx.x
     -lF77 -lV77' to the link command.


File: g77.info,  Node: Other Languages,  Next: Debugging and Interfacing,  Prev: Other Compilers,  Up: Top

12 Other Languages
******************

_Note: This portion of the documentation definitely needs a lot of
work!_

* Menu:

* Interoperating with C and C++::


File: g77.info,  Node: Interoperating with C and C++,  Up: Other Languages

12.1 Tools and advice for interoperating with C and C++
=======================================================

The following discussion assumes that you are running `g77' in `f2c'
compatibility mode, i.e. not using `-fno-f2c'.  It provides some advice
about quick and simple techniques for linking Fortran and C (or C++),
the most common requirement.  For the full story consult the
description of code generation.  *Note Debugging and Interfacing::.

   When linking Fortran and C, it's usually best to use `g77' to do the
linking so that the correct libraries are included (including the maths
one).  If you're linking with C++ you will want to add `-lstdc++',
`-lg++' or whatever.  If you need to use another driver program (or
`ld' directly), you can find out what linkage options `g77' passes by
running `g77 -v'.

* Menu:

* C Interfacing Tools::
* C Access to Type Information::
* f2c Skeletons and Prototypes::
* C++ Considerations::
* Startup Code::


File: g77.info,  Node: C Interfacing Tools,  Next: C Access to Type Information,  Up: Interoperating with C and C++

12.1.1 C Interfacing Tools
--------------------------

Even if you don't actually use it as a compiler, `f2c' from
`ftp://ftp.netlib.org/f2c/src', can be a useful tool when you're
interfacing (linking) Fortran and C.  *Note Generating Skeletons and
Prototypes with `f2c': f2c Skeletons and Prototypes.

   To use `f2c' for this purpose you only need retrieve and build the
`src' directory from the distribution, consult the `README'
instructions there for machine-specifics, and install the `f2c' program
on your path.

   Something else that might be useful is `cfortran.h' from
`ftp://zebra.desy.de/cfortran'.  This is a fairly general tool which
can be used to generate interfaces for calling in both directions
between Fortran and C.  It can be used in `f2c' mode with
`g77'--consult its documentation for details.


File: g77.info,  Node: C Access to Type Information,  Next: f2c Skeletons and Prototypes,  Prev: C Interfacing Tools,  Up: Interoperating with C and C++

12.1.2 Accessing Type Information in C
--------------------------------------

Generally, C code written to link with `g77' code--calling and/or being
called from Fortran--should `#include <g2c.h>' to define the C versions
of the Fortran types.  Don't assume Fortran `INTEGER' types correspond
to C `int's, for instance; instead, declare them as `integer', a type
defined by `g2c.h'.  `g2c.h' is installed where `gcc' will find it by
default, assuming you use a copy of `gcc' compatible with `g77',
probably built at the same time as `g77'.


File: g77.info,  Node: f2c Skeletons and Prototypes,  Next: C++ Considerations,  Prev: C Access to Type Information,  Up: Interoperating with C and C++

12.1.3 Generating Skeletons and Prototypes with `f2c'
-----------------------------------------------------

A simple and foolproof way to write `g77'-callable C routines--e.g. to
interface with an existing library--is to write a file (named, for
example, `fred.f') of dummy Fortran skeletons comprising just the
declaration of the routine(s) and dummy arguments plus `END' statements.
Then run `f2c' on file `fred.f' to produce `fred.c' into which you can
edit useful code, confident the calling sequence is correct, at least.
(There are some errors otherwise commonly made in generating C
interfaces with `f2c' conventions, such as not using `doublereal' as
the return type of a `REAL' `FUNCTION'.)

   `f2c' also can help with calling Fortran from C, using its `-P'
option to generate C prototypes appropriate for calling the Fortran.(1)
If the Fortran code containing any routines to be called from C is in
file `joe.f', use the command `f2c -P joe.f' to generate the file
`joe.P' containing prototype information.  `#include' this in the C
which has to call the Fortran routines to make sure you get it right.

   *Note Arrays (DIMENSION): Arrays, for information on the differences
between the way Fortran (including compilers like `g77') and C handle
arrays.

   ---------- Footnotes ----------

   (1) The files generated like this can also be used for inter-unit
consistency checking of dummy and actual arguments, although the
`ftnchek' tool from `ftp://ftp.netlib.org/fortran' or
`ftp://ftp.dsm.fordham.edu' is probably better for this purpose.


File: g77.info,  Node: C++ Considerations,  Next: Startup Code,  Prev: f2c Skeletons and Prototypes,  Up: Interoperating with C and C++

12.1.4 C++ Considerations
-------------------------

`f2c' can be used to generate suitable code for compilation with a C++
system using the `-C++' option.  The important thing about linking
`g77'-compiled code with C++ is that the prototypes for the `g77'
routines must specify C linkage to avoid name mangling.  So, use an
`extern "C"' declaration.  `f2c''s `-C++' option will not take care of
this when generating skeletons or prototype files as above, however, it
will avoid clashes with C++ reserved words in addition to those in C.


File: g77.info,  Node: Startup Code,  Prev: C++ Considerations,  Up: Interoperating with C and C++

12.1.5 Startup Code
-------------------

Unlike with some runtime systems, it shouldn't be necessary (unless
there are bugs) to use a Fortran main program unit to ensure the
runtime--specifically the I/O system--is initialized.

   However, to use the `g77' intrinsics `GETARG' and `IARGC', either
the `main' routine from the `libg2c' library must be used, or the
`f_setarg' routine (new as of `egcs' version 1.1 and `g77' version
0.5.23) must be called with the appropriate `argc' and `argv' arguments
prior to the program calling `GETARG' or `IARGC'.

   To provide more flexibility for mixed-language programming involving
`g77' while allowing for shared libraries, as of `egcs' version 1.1 and
`g77' version 0.5.23, `g77''s `main' routine in `libg2c' does the
following, in order:

  1. Calls `f_setarg' with the incoming `argc' and `argv' arguments, in
     the same order as for `main' itself.

     This sets up the command-line environment for `GETARG' and `IARGC'.

  2. Calls `f_setsig' (with no arguments).

     This sets up the signaling and exception environment.

  3. Calls `f_init' (with no arguments).

     This initializes the I/O environment, though that should not be
     necessary, as all I/O functions in `libf2c' are believed to call
     `f_init' automatically, if necessary.

     (A future version of `g77' might skip this explicit step, to speed
     up normal exit of a program.)

  4. Arranges for `f_exit' to be called (with no arguments) when the
     program exits.

     This ensures that the I/O environment is properly shut down before
     the program exits normally.  Otherwise, output buffers might not
     be fully flushed, scratch files might not be deleted, and so on.

     The simple way `main' does this is to call `f_exit' itself after
     calling `MAIN__' (in the next step).

     However, this does not catch the cases where the program might
     call `exit' directly, instead of using the `EXIT' intrinsic
     (implemented as `exit_' in `libf2c').

     So, `main' attempts to use the operating environment's `onexit' or
     `atexit' facility, if available, to cause `f_exit' to be called
     automatically upon any invocation of `exit'.

  5. Calls `MAIN__' (with no arguments).

     This starts executing the Fortran main program unit for the
     application.  (Both `g77' and `f2c' currently compile a main
     program unit so that its global name is `MAIN__'.)

  6. If no `onexit' or `atexit' is provided by the system, calls
     `f_exit'.

  7. Calls `exit' with a zero argument, to signal a successful program
     termination.

  8. Returns a zero value to the caller, to signal a successful program
     termination, in case `exit' doesn't exit on the system.

   All of the above names are C `extern' names, i.e. not mangled.

   When using the `main' procedure provided by `g77' without a Fortran
main program unit, you need to provide `MAIN__' as the entry point for
your C code.  (Make sure you link the object file that defines that
entry point with the rest of your program.)

   To provide your own `main' procedure in place of `g77''s, make sure
you specify the object file defining that procedure _before_ `-lg2c' on
the `g77' command line.  Since the `-lg2c' option is implicitly
provided, this is usually straightforward.  (Use the `--verbose' option
to see how and where `g77' implicitly adds `-lg2c' in a command line
that will link the program.  Feel free to specify `-lg2c' explicitly,
as appropriate.)

   However, when providing your own `main', make sure you perform the
appropriate tasks in the appropriate order.  For example, if your
`main' does not call `f_setarg', make sure the rest of your application
does not call `GETARG' or `IARGC'.

   And, if your `main' fails to ensure that `f_exit' is called upon
program exit, some files might end up incompletely written, some
scratch files might be left lying around, and some existing files being
written might be left with old data not properly truncated at the end.

   Note that, generally, the `g77' operating environment does not
depend on a procedure named `MAIN__' actually being called prior to any
other `g77'-compiled code.  That is, `MAIN__' does not, itself, set up
any important operating-environment characteristics upon which other
code might depend.  This might change in future versions of `g77', with
appropriate notification in the release notes.

   For more information, consult the source code for the above routines.
These are in `gcc/libf2c/libF77/', named `main.c', `setarg.c',
`setsig.c', `getarg_.c', and `iargc_.c'.

   Also, the file `gcc/gcc/f/com.c' contains the code `g77' uses to
open-code (inline) references to `IARGC'.


File: g77.info,  Node: Debugging and Interfacing,  Next: Collected Fortran Wisdom,  Prev: Other Languages,  Up: Top

13 Debugging and Interfacing
****************************

GNU Fortran currently generates code that is object-compatible with the
`f2c' converter.  Also, it avoids limitations in the current GBE, such
as the inability to generate a procedure with multiple entry points, by
generating code that is structured differently (in terms of procedure
names, scopes, arguments, and so on) than might be expected.

   As a result, writing code in other languages that calls on, is
called by, or shares in-memory data with `g77'-compiled code generally
requires some understanding of the way `g77' compiles code for various
constructs.

   Similarly, using a debugger to debug `g77'-compiled code, even if
that debugger supports native Fortran debugging, generally requires
this sort of information.

   This section describes some of the basic information on how `g77'
compiles code for constructs involving interfaces to other languages
and to debuggers.

   _Caution:_ Much or all of this information pertains to only the
current release of `g77', sometimes even to using certain compiler
options with `g77' (such as `-fno-f2c').  Do not write code that
depends on this information without clearly marking said code as
nonportable and subject to review for every new release of `g77'.  This
information is provided primarily to make debugging of code generated
by this particular release of `g77' easier for the user, and partly to
make writing (generally nonportable) interface code easier.  Both of
these activities require tracking changes in new version of `g77' as
they are installed, because new versions can change the behaviors
described in this section.

* Menu:

* Main Program Unit::  How `g77' compiles a main program unit.
* Procedures::         How `g77' constructs parameter lists
                       for procedures.
* Functions::          Functions returning floating-point or character data.
* Names::              Naming of user-defined variables, procedures, etc.
* Common Blocks::      Accessing common variables while debugging.
* Local Equivalence Areas::  Accessing `EQUIVALENCE' while debugging.
* Complex Variables::  How `g77' performs complex arithmetic.
* Arrays::             Dealing with (possibly multi-dimensional) arrays.
* Adjustable Arrays::  Special consideration for adjustable arrays.
* Alternate Entry Points::  How `g77' implements alternate `ENTRY'.
* Alternate Returns::  How `g77' handles alternate returns.
* Assigned Statement Labels::  How `g77' handles `ASSIGN'.
* Run-time Library Errors::  Meanings of some `IOSTAT=' values.


File: g77.info,  Node: Main Program Unit,  Next: Procedures,  Up: Debugging and Interfacing

13.1 Main Program Unit (PROGRAM)
================================

When `g77' compiles a main program unit, it gives it the public
procedure name `MAIN__'.  The `libg2c' library has the actual `main()'
procedure as is typical of C-based environments, and it is this
procedure that performs some initial start-up activity and then calls
`MAIN__'.

   Generally, `g77' and `libg2c' are designed so that you need not
include a main program unit written in Fortran in your program--it can
be written in C or some other language.  Especially for I/O handling,
this is the case, although `g77' version 0.5.16 includes a bug fix for
`libg2c' that solved a problem with using the `OPEN' statement as the
first Fortran I/O activity in a program without a Fortran main program
unit.

   However, if you don't intend to use `g77' (or `f2c') to compile your
main program unit--that is, if you intend to compile a `main()'
procedure using some other language--you should carefully examine the
code for `main()' in `libg2c', found in the source file
`gcc/libf2c/libF77/main.c', to see what kinds of things might need to
be done by your `main()' in order to provide the Fortran environment
your Fortran code is expecting.

   For example, `libg2c''s `main()' sets up the information used by the
`IARGC' and `GETARG' intrinsics.  Bypassing `libg2c''s `main()' without
providing a substitute for this activity would mean that invoking
`IARGC' and `GETARG' would produce undefined results.

   When debugging, one implication of the fact that `main()', which is
the place where the debugged program "starts" from the debugger's point
of view, is in `libg2c' is that you won't be starting your Fortran
program at a point you recognize as your Fortran code.

   The standard way to get around this problem is to set a break point
(a one-time, or temporary, break point will do) at the entrance to
`MAIN__', and then run the program.  A convenient way to do so is to
add the `gdb' command

     tbreak MAIN__

to the file `.gdbinit' in the directory in which you're debugging
(using `gdb').

   After doing this, the debugger will see the current execution point
of the program as at the beginning of the main program unit of your
program.

   Of course, if you really want to set a break point at some other
place in your program and just start the program running, without first
breaking at `MAIN__', that should work fine.


File: g77.info,  Node: Procedures,  Next: Functions,  Prev: Main Program Unit,  Up: Debugging and Interfacing

13.2 Procedures (SUBROUTINE and FUNCTION)
=========================================

Currently, `g77' passes arguments via reference--specifically, by
passing a pointer to the location in memory of a variable, array, array
element, a temporary location that holds the result of evaluating an
expression, or a temporary or permanent location that holds the value
of a constant.

   Procedures that accept `CHARACTER' arguments are implemented by
`g77' so that each `CHARACTER' argument has two actual arguments.

   The first argument occupies the expected position in the argument
list and has the user-specified name.  This argument is a pointer to an
array of characters, passed by the caller.

   The second argument is appended to the end of the user-specified
calling sequence and is named `__g77_length_X', where X is the
user-specified name.  This argument is of the C type `ftnlen' (see
`gcc/libf2c/g2c.h.in' for information on that type) and is the number
of characters the caller has allocated in the array pointed to by the
first argument.

   A procedure will ignore the length argument if `X' is not declared
`CHARACTER*(*)', because for other declarations, it knows the length.
Not all callers necessarily "know" this, however, which is why they all
pass the extra argument.

   The contents of the `CHARACTER' argument are specified by the
address passed in the first argument (named after it).  The procedure
can read or write these contents as appropriate.

   When more than one `CHARACTER' argument is present in the argument
list, the length arguments are appended in the order the original
arguments appear.  So `CALL FOO('HI','THERE')' is implemented in C as
`foo("hi","there",2,5);', ignoring the fact that `g77' does not provide
the trailing null bytes on the constant strings (`f2c' does provide
them, but they are unnecessary in a Fortran environment, and you should
not expect them to be there).

   Note that the above information applies to `CHARACTER' variables and
arrays *only*.  It does *not* apply to external `CHARACTER' functions
or to intrinsic `CHARACTER' functions.  That is, no second length
argument is passed to `FOO' in this case:

     CHARACTER X
     EXTERNAL X
     CALL FOO(X)

Nor does `FOO' expect such an argument in this case:

     SUBROUTINE FOO(X)
     CHARACTER X
     EXTERNAL X

   Because of this implementation detail, if a program has a bug such
that there is disagreement as to whether an argument is a procedure,
and the type of the argument is `CHARACTER', subtle symptoms might
appear.


File: g77.info,  Node: Functions,  Next: Names,  Prev: Procedures,  Up: Debugging and Interfacing

13.3 Functions (FUNCTION and RETURN)
====================================

`g77' handles in a special way functions that return the following
types:

   * `CHARACTER'

   * `COMPLEX'

   * `REAL(KIND=1)'

   For `CHARACTER', `g77' implements a subroutine (a C function
returning `void') with two arguments prepended: `__g77_result', which
the caller passes as a pointer to a `char' array expected to hold the
return value, and `__g77_length', which the caller passes as an
`ftnlen' value specifying the length of the return value as declared in
the calling program.  For `CHARACTER*(*)', the called function uses
`__g77_length' to determine the size of the array that `__g77_result'
points to; otherwise, it ignores that argument.

   For `COMPLEX', when `-ff2c' is in force, `g77' implements a
subroutine with one argument prepended: `__g77_result', which the
caller passes as a pointer to a variable of the type of the function.
The called function writes the return value into this variable instead
of returning it as a function value.  When `-fno-f2c' is in force,
`g77' implements a `COMPLEX' function as `gcc''s `__complex__ float' or
`__complex__ double' function (or an emulation thereof, when
`-femulate-complex' is in effect), returning the result of the function
in the same way as `gcc' would.

   For `REAL(KIND=1)', when `-ff2c' is in force, `g77' implements a
function that actually returns `REAL(KIND=2)' (typically C's `double'
type).  When `-fno-f2c' is in force, `REAL(KIND=1)' functions return
`float'.


File: g77.info,  Node: Names,  Next: Common Blocks,  Prev: Functions,  Up: Debugging and Interfacing

13.4 Names
==========

Fortran permits each implementation to decide how to represent names as
far as how they're seen in other contexts, such as debuggers and when
interfacing to other languages, and especially as far as how casing is
handled.

   External names--names of entities that are public, or "accessible",
to all modules in a program--normally have an underscore (`_') appended
by `g77', to generate code that is compatible with `f2c'.  External
names include names of Fortran things like common blocks, external
procedures (subroutines and functions, but not including statement
functions, which are internal procedures), and entry point names.

   However, use of the `-fno-underscoring' option disables this kind of
transformation of external names (though inhibiting the transformation
certainly improves the chances of colliding with incompatible externals
written in other languages--but that might be intentional.

   When `-funderscoring' is in force, any name (external or local) that
already has at least one underscore in it is implemented by `g77' by
appending two underscores.  (This second underscore can be disabled via
the `-fno-second-underscore' option.)  External names are changed this
way for `f2c' compatibility.  Local names are changed this way to avoid
collisions with external names that are different in the source
code--`f2c' does the same thing, but there's no compatibility issue
there except for user expectations while debugging.

   For example:

     Max_Cost = 0

Here, a user would, in the debugger, refer to this variable using the
name `max_cost__' (or `MAX_COST__' or `Max_Cost__', as described below).
(We hope to improve `g77' in this regard in the future--don't write
scripts depending on this behavior!  Also, consider experimenting with
the `-fno-underscoring' option to try out debugging without having to
massage names by hand like this.)

   `g77' provides a number of command-line options that allow the user
to control how case mapping is handled for source files.  The default
is the traditional UNIX model for Fortran compilers--names are mapped
to lower case.  Other command-line options can be specified to map
names to upper case, or to leave them exactly as written in the source
file.

   For example:

     Foo = 9.436

Here, it is normally the case that the variable assigned will be named
`foo'.  This would be the name to enter when using a debugger to access
the variable.

   However, depending on the command-line options specified, the name
implemented by `g77' might instead be `FOO' or even `Foo', thus
affecting how debugging is done.

   Also:

     Call Foo

This would normally call a procedure that, if it were in a separate C
program, be defined starting with the line:

     void foo_()

However, `g77' command-line options could be used to change the casing
of names, resulting in the name `FOO_' or `Foo_' being given to the
procedure instead of `foo_', and the `-fno-underscoring' option could
be used to inhibit the appending of the underscore to the name.


File: g77.info,  Node: Common Blocks,  Next: Local Equivalence Areas,  Prev: Names,  Up: Debugging and Interfacing

13.5 Common Blocks (COMMON)
===========================

`g77' names and lays out `COMMON' areas the same way `f2c' does, for
compatibility with `f2c'.


File: g77.info,  Node: Local Equivalence Areas,  Next: Complex Variables,  Prev: Common Blocks,  Up: Debugging and Interfacing

13.6 Local Equivalence Areas (EQUIVALENCE)
==========================================

`g77' treats storage-associated areas involving a `COMMON' block as
explained in the section on common blocks.

   A local `EQUIVALENCE' area is a collection of variables and arrays
connected to each other in any way via `EQUIVALENCE', none of which are
listed in a `COMMON' statement.

   (_Note:_ `g77' version 0.5.18 and earlier chose the name for X using
a different method when more than one name was in the list of names of
entities placed at the beginning of the array.  Though the
documentation specified that the first name listed in the `EQUIVALENCE'
statements was chosen for X, `g77' in fact chose the name using a
method that was so complicated, it seemed easier to change it to an
alphabetical sort than to describe the previous method in the
documentation.)


File: g77.info,  Node: Complex Variables,  Next: Arrays,  Prev: Local Equivalence Areas,  Up: Debugging and Interfacing

13.7 Complex Variables (COMPLEX)
================================

As of 0.5.20, `g77' defaults to handling `COMPLEX' types (and related
intrinsics, constants, functions, and so on) in a manner that makes
direct debugging involving these types in Fortran language mode
difficult.

   Essentially, `g77' implements these types using an internal
construct similar to C's `struct', at least as seen by the `gcc' back
end.

   Currently, the back end, when outputting debugging info with the
compiled code for the assembler to digest, does not detect these
`struct' types as being substitutes for Fortran complex.  As a result,
the Fortran language modes of debuggers such as `gdb' see these types
as C `struct' types, which they might or might not support.

   Until this is fixed, switch to C language mode to work with entities
of `COMPLEX' type and then switch back to Fortran language mode
afterward.  (In `gdb', this is accomplished via `set lang c' and either
`set lang fortran' or `set lang auto'.)


File: g77.info,  Node: Arrays,  Next: Adjustable Arrays,  Prev: Complex Variables,  Up: Debugging and Interfacing

13.8 Arrays (DIMENSION)
=======================

Fortran uses "column-major ordering" in its arrays.  This differs from
other languages, such as C, which use "row-major ordering".  The
difference is that, with Fortran, array elements adjacent to each other
in memory differ in the _first_ subscript instead of the last;
`A(5,10,20)' immediately follows `A(4,10,20)', whereas with row-major
ordering it would follow `A(5,10,19)'.

   This consideration affects not only interfacing with and debugging
Fortran code, it can greatly affect how code is designed and written,
especially when code speed and size is a concern.

   Fortran also differs from C, a popular language for interfacing and
to support directly in debuggers, in the way arrays are treated.  In C,
arrays are single-dimensional and have interesting relationships to
pointers, neither of which is true for Fortran.  As a result, dealing
with Fortran arrays from within an environment limited to C concepts
can be challenging.

   For example, accessing the array element `A(5,10,20)' is easy enough
in Fortran (use `A(5,10,20)'), but in C some difficult machinations are
needed.  First, C would treat the A array as a single-dimension array.
Second, C does not understand low bounds for arrays as does Fortran.
Third, C assumes a low bound of zero (0), while Fortran defaults to a
low bound of one (1) and can supports an arbitrary low bound.
Therefore, calculations must be done to determine what the C equivalent
of `A(5,10,20)' would be, and these calculations require knowing the
dimensions of `A'.

   For `DIMENSION A(2:11,21,0:29)', the calculation of the offset of
`A(5,10,20)' would be:

       (5-2)
     + (10-1)*(11-2+1)
     + (20-0)*(11-2+1)*(21-1+1)
     = 4293

So the C equivalent in this case would be `a[4293]'.

   When using a debugger directly on Fortran code, the C equivalent
might not work, because some debuggers cannot understand the notion of
low bounds other than zero.  However, unlike `f2c', `g77' does inform
the GBE that a multi-dimensional array (like `A' in the above example)
is really multi-dimensional, rather than a single-dimensional array, so
at least the dimensionality of the array is preserved.

   Debuggers that understand Fortran should have no trouble with
nonzero low bounds, but for non-Fortran debuggers, especially C
debuggers, the above example might have a C equivalent of `a[4305]'.
This calculation is arrived at by eliminating the subtraction of the
lower bound in the first parenthesized expression on each line--that
is, for `(5-2)' substitute `(5)', for `(10-1)' substitute `(10)', and
for `(20-0)' substitute `(20)'.  Actually, the implication of this can
be that the expression `*(&a[2][1][0] + 4293)' works fine, but that
`a[20][10][5]' produces the equivalent of `*(&a[0][0][0] + 4305)'
because of the missing lower bounds.

   Come to think of it, perhaps the behavior is due to the debugger
internally compensating for the lower bounds by offsetting the base
address of `a', leaving `&a' set lower, in this case, than
`&a[2][1][0]' (the address of its first element as identified by
subscripts equal to the corresponding lower bounds).

   You know, maybe nobody really needs to use arrays.


File: g77.info,  Node: Adjustable Arrays,  Next: Alternate Entry Points,  Prev: Arrays,  Up: Debugging and Interfacing

13.9 Adjustable Arrays (DIMENSION)
==================================

Adjustable and automatic arrays in Fortran require the implementation
(in this case, the `g77' compiler) to "memorize" the expressions that
dimension the arrays each time the procedure is invoked.  This is so
that subsequent changes to variables used in those expressions, made
during execution of the procedure, do not have any effect on the
dimensions of those arrays.

   For example:

     REAL ARRAY(5)
     DATA ARRAY/5*2/
     CALL X(ARRAY, 5)
     END
     SUBROUTINE X(A, N)
     DIMENSION A(N)
     N = 20
     PRINT *, N, A
     END

Here, the implementation should, when running the program, print
something like:

     20   2.  2.  2.  2.  2.

Note that this shows that while the value of `N' was successfully
changed, the size of the `A' array remained at 5 elements.

   To support this, `g77' generates code that executes before any user
code (and before the internally generated computed `GOTO' to handle
alternate entry points, as described below) that evaluates each
(nonconstant) expression in the list of subscripts for an array, and
saves the result of each such evaluation to be used when determining
the size of the array (instead of re-evaluating the expressions).

   So, in the above example, when `X' is first invoked, code is
executed that copies the value of `N' to a temporary.  And that same
temporary serves as the actual high bound for the single dimension of
the `A' array (the low bound being the constant 1).  Since the user
program cannot (legitimately) change the value of the temporary during
execution of the procedure, the size of the array remains constant
during each invocation.

   For alternate entry points, the code `g77' generates takes into
account the possibility that a dummy adjustable array is not actually
passed to the actual entry point being invoked at that time.  In that
case, the public procedure implementing the entry point passes to the
master private procedure implementing all the code for the entry points
a `NULL' pointer where a pointer to that adjustable array would be
expected.  The `g77'-generated code doesn't attempt to evaluate any of
the expressions in the subscripts for an array if the pointer to that
array is `NULL' at run time in such cases.  (Don't depend on this
particular implementation by writing code that purposely passes `NULL'
pointers where the callee expects adjustable arrays, even if you know
the callee won't reference the arrays--nor should you pass `NULL'
pointers for any dummy arguments used in calculating the bounds of such
arrays or leave undefined any values used for that purpose in
COMMON--because the way `g77' implements these things might change in
the future!)


File: g77.info,  Node: Alternate Entry Points,  Next: Alternate Returns,  Prev: Adjustable Arrays,  Up: Debugging and Interfacing

13.10 Alternate Entry Points (ENTRY)
====================================

The GBE does not understand the general concept of alternate entry
points as Fortran provides via the ENTRY statement.  `g77' gets around
this by using an approach to compiling procedures having at least one
`ENTRY' statement that is almost identical to the approach used by
`f2c'.  (An alternate approach could be used that would probably
generate faster, but larger, code that would also be a bit easier to
debug.)

   Information on how `g77' implements `ENTRY' is provided for those
trying to debug such code.  The choice of implementation seems unlikely
to affect code (compiled in other languages) that interfaces to such
code.

   `g77' compiles exactly one public procedure for the primary entry
point of a procedure plus each `ENTRY' point it specifies, as usual.
That is, in terms of the public interface, there is no difference
between

     SUBROUTINE X
     END
     SUBROUTINE Y
     END

and:

     SUBROUTINE X
     ENTRY Y
     END

   The difference between the above two cases lies in the code compiled
for the `X' and `Y' procedures themselves, plus the fact that, for the
second case, an extra internal procedure is compiled.

   For every Fortran procedure with at least one `ENTRY' statement,
`g77' compiles an extra procedure named `__g77_masterfun_X', where X is
the name of the primary entry point (which, in the above case, using
the standard compiler options, would be `x_' in C).

   This extra procedure is compiled as a private procedure--that is, a
procedure not accessible by name to separately compiled modules.  It
contains all the code in the program unit, including the code for the
primary entry point plus for every entry point.  (The code for each
public procedure is quite short, and explained later.)

   The extra procedure has some other interesting characteristics.

   The argument list for this procedure is invented by `g77'.  It
contains a single integer argument named `__g77_which_entrypoint',
passed by value (as in Fortran's `%VAL()' intrinsic), specifying the
entry point index--0 for the primary entry point, 1 for the first entry
point (the first `ENTRY' statement encountered), 2 for the second entry
point, and so on.

   It also contains, for functions returning `CHARACTER' and (when
`-ff2c' is in effect) `COMPLEX' functions, and for functions returning
different types among the `ENTRY' statements (e.g. `REAL FUNCTION R()'
containing `ENTRY I()'), an argument named `__g77_result' that is
expected at run time to contain a pointer to where to store the result
of the entry point.  For `CHARACTER' functions, this storage area is an
array of the appropriate number of characters; for `COMPLEX' functions,
it is the appropriate area for the return type; for
multiple-return-type functions, it is a union of all the supported
return types (which cannot include `CHARACTER', since combining
`CHARACTER' and non-`CHARACTER' return types via `ENTRY' in a single
function is not supported by `g77').

   For `CHARACTER' functions, the `__g77_result' argument is followed
by yet another argument named `__g77_length' that, at run time,
specifies the caller's expected length of the returned value.  Note
that only `CHARACTER*(*)' functions and entry points actually make use
of this argument, even though it is always passed by all callers of
public `CHARACTER' functions (since the caller does not generally know
whether such a function is `CHARACTER*(*)' or whether there are any
other callers that don't have that information).

   The rest of the argument list is the union of all the arguments
specified for all the entry points (in their usual forms, e.g.
`CHARACTER' arguments have extra length arguments, all appended at the
end of this list).  This is considered the "master list" of arguments.

   The code for this procedure has, before the code for the first
executable statement, code much like that for the following Fortran
statement:

            GOTO (100000,100001,100002), __g77_which_entrypoint
     100000 ...code for primary entry point...
     100001 ...code immediately following first ENTRY statement...
     100002 ...code immediately following second ENTRY statement...

(Note that invalid Fortran statement labels and variable names are used
in the above example to highlight the fact that it represents code
generated by the `g77' internals, not code to be written by the user.)

   It is this code that, when the procedure is called, picks which
entry point to start executing.

   Getting back to the public procedures (`x' and `Y' in the original
example), those procedures are fairly simple.  Their interfaces are
just like they would be if they were self-contained procedures (without
`ENTRY'), of course, since that is what the callers expect.  Their code
consists of simply calling the private procedure, described above, with
the appropriate extra arguments (the entry point index, and perhaps a
pointer to a multiple-type- return variable, local to the public
procedure, that contains all the supported returnable non-character
types).  For arguments that are not listed for a given entry point that
are listed for other entry points, and therefore that are in the
"master list" for the private procedure, null pointers (in C, the
`NULL' macro) are passed.  Also, for entry points that are part of a
multiple-type- returning function, code is compiled after the call of
the private procedure to extract from the multi-type union the
appropriate result, depending on the type of the entry point in
question, returning that result to the original caller.

   When debugging a procedure containing alternate entry points, you
can either set a break point on the public procedure itself (e.g.  a
break point on `X' or `Y') or on the private procedure that contains
most of the pertinent code (e.g. `__g77_masterfun_X').  If you do the
former, you should use the debugger's command to "step into" the called
procedure to get to the actual code; with the latter approach, the
break point leaves you right at the actual code, skipping over the
public entry point and its call to the private procedure (unless you
have set a break point there as well, of course).

   Further, the list of dummy arguments that is visible when the
private procedure is active is going to be the expanded version of the
list for whichever particular entry point is active, as explained
above, and the way in which return values are handled might well be
different from how they would be handled for an equivalent single-entry
function.


File: g77.info,  Node: Alternate Returns,  Next: Assigned Statement Labels,  Prev: Alternate Entry Points,  Up: Debugging and Interfacing

13.11 Alternate Returns (SUBROUTINE and RETURN)
===============================================

Subroutines with alternate returns (e.g. `SUBROUTINE X(*)' and `CALL
X(*50)') are implemented by `g77' as functions returning the C `int'
type.  The actual alternate-return arguments are omitted from the
calling sequence.  Instead, the caller uses the return value to do a
rough equivalent of the Fortran computed-`GOTO' statement, as in `GOTO
(50), X()' in the example above (where `X' is quietly declared as an
`INTEGER(KIND=1)' function), and the callee just returns whatever
integer is specified in the `RETURN' statement for the subroutine For
example, `RETURN 1' is implemented as `X = 1' followed by `RETURN' in
C, and `RETURN' by itself is `X = 0' and `RETURN').


File: g77.info,  Node: Assigned Statement Labels,  Next: Run-time Library Errors,  Prev: Alternate Returns,  Up: Debugging and Interfacing

13.12 Assigned Statement Labels (ASSIGN and GOTO)
=================================================

For portability to machines where a pointer (such as to a label, which
is how `g77' implements `ASSIGN' and its relatives, the assigned-`GOTO'
and assigned-`FORMAT'-I/O statements) is wider (bitwise) than an
`INTEGER(KIND=1)', `g77' uses a different memory location to hold the
`ASSIGN'ed value of a variable than it does the numerical value in that
variable, unless the variable is wide enough (can hold enough bits).

   In particular, while `g77' implements

     I = 10

as, in C notation, `i = 10;', it implements

     ASSIGN 10 TO I

as, in GNU's extended C notation (for the label syntax),
`__g77_ASSIGN_I = &&L10;' (where `L10' is just a massaging of the
Fortran label `10' to make the syntax C-like; `g77' doesn't actually
generate the name `L10' or any other name like that, since debuggers
cannot access labels anyway).

   While this currently means that an `ASSIGN' statement does not
overwrite the numeric contents of its target variable, _do not_ write
any code depending on this feature.  `g77' has already changed this
implementation across versions and might do so in the future.  This
information is provided only to make debugging Fortran programs
compiled with the current version of `g77' somewhat easier.  If there's
no debugger-visible variable named `__g77_ASSIGN_I' in a program unit
that does `ASSIGN 10 TO I', that probably means `g77' has decided it
can store the pointer to the label directly into `I' itself.

   *Note Ugly Assigned Labels::, for information on a command-line
option to force `g77' to use the same storage for both normal and
assigned-label uses of a variable.


File: g77.info,  Node: Run-time Library Errors,  Prev: Assigned Statement Labels,  Up: Debugging and Interfacing

13.13 Run-time Library Errors
=============================

The `libg2c' library currently has the following table to relate error
code numbers, returned in `IOSTAT=' variables, to messages.  This
information should, in future versions of this document, be expanded
upon to include detailed descriptions of each message.

   In line with good coding practices, any of the numbers in the list
below should _not_ be directly written into Fortran code you write.
Instead, make a separate `INCLUDE' file that defines `PARAMETER' names
for them, and use those in your code, so you can more easily change the
actual numbers in the future.

   The information below is culled from the definition of `F_err' in
`f/runtime/libI77/err.c' in the `g77' source tree.

     100: "error in format"
     101: "illegal unit number"
     102: "formatted io not allowed"
     103: "unformatted io not allowed"
     104: "direct io not allowed"
     105: "sequential io not allowed"
     106: "can't backspace file"
     107: "null file name"
     108: "can't stat file"
     109: "unit not connected"
     110: "off end of record"
     111: "truncation failed in endfile"
     112: "incomprehensible list input"
     113: "out of free space"
     114: "unit not connected"
     115: "read unexpected character"
     116: "bad logical input field"
     117: "bad variable type"
     118: "bad namelist name"
     119: "variable not in namelist"
     120: "no end record"
     121: "variable count incorrect"
     122: "subscript for scalar variable"
     123: "invalid array section"
     124: "substring out of bounds"
     125: "subscript out of bounds"
     126: "can't read file"
     127: "can't write file"
     128: "'new' file exists"
     129: "can't append to file"
     130: "non-positive record number"
     131: "I/O started while already doing I/O"


File: g77.info,  Node: Collected Fortran Wisdom,  Next: Trouble,  Prev: Debugging and Interfacing,  Up: Top

14 Collected Fortran Wisdom
***************************

Most users of `g77' can be divided into two camps:

   * Those writing new Fortran code to be compiled by `g77'.

   * Those using `g77' to compile existing, "legacy" code.

   Users writing new code generally understand most of the necessary
aspects of Fortran to write "mainstream" code, but often need help
deciding how to handle problems, such as the construction of libraries
containing `BLOCK DATA'.

   Users dealing with "legacy" code sometimes don't have much
experience with Fortran, but believe that the code they're compiling
already works when compiled by other compilers (and might not
understand why, as is sometimes the case, it doesn't work when compiled
by `g77').

   The following information is designed to help users do a better job
coping with existing, "legacy" Fortran code, and with writing new code
as well.

* Menu:

* Advantages Over f2c::        If `f2c' is so great, why `g77'?
* Block Data and Libraries::   How `g77' solves a common problem.
* Loops::                      Fortran `DO' loops surprise many people.
* Working Programs::           Getting programs to work should be done first.
* Overly Convenient Options::  Temptations to avoid, habits to not form.
* Faster Programs::            Everybody wants these, but at what cost?


File: g77.info,  Node: Advantages Over f2c,  Next: Block Data and Libraries,  Up: Collected Fortran Wisdom

14.1 Advantages Over f2c
========================

Without `f2c', `g77' would have taken much longer to do and probably
not been as good for quite a while.  Sometimes people who notice how
much `g77' depends on, and documents encouragement to use, `f2c' ask
why `g77' was created if `f2c' already existed.

   This section gives some basic answers to these questions, though it
is not intended to be comprehensive.

* Menu:

* Language Extensions::  Features used by Fortran code.
* Diagnostic Abilities:: Abilities to spot problems early.
* Compiler Options::     Features helpful to accommodate legacy code, etc.
* Compiler Speed::       Speed of the compilation process.
* Program Speed::        Speed of the generated, optimized code.
* Ease of Debugging::    Debugging ease-of-use at the source level.
* Character and Hollerith Constants::  A byte saved is a byte earned.


File: g77.info,  Node: Language Extensions,  Next: Diagnostic Abilities,  Up: Advantages Over f2c

14.1.1 Language Extensions
--------------------------

`g77' offers several extensions to FORTRAN 77 language that `f2c'
doesn't:

   * Automatic arrays

   * `CYCLE' and `EXIT'

   * Construct names

   * `SELECT CASE'

   * `KIND=' and `LEN=' notation

   * Semicolon as statement separator

   * Constant expressions in `FORMAT' statements (such as
     `FORMAT(I<J>)', where `J' is a `PARAMETER' named constant)

   * `MvBits' intrinsic

   * `libU77' (Unix-compatibility) library, with routines known to
     compiler as intrinsics (so they work even when compiler options
     are used to change the interfaces used by Fortran routines)

   `g77' also implements iterative `DO' loops so that they work even in
the presence of certain "extreme" inputs, unlike `f2c'.  *Note Loops::.

   However, `f2c' offers a few that `g77' doesn't, such as:

   * Intrinsics in `PARAMETER' statements

   * Array bounds expressions (such as `REAL M(N(2))')

   * `AUTOMATIC' statement

   It is expected that `g77' will offer some or all of these missing
features at some time in the future.


File: g77.info,  Node: Diagnostic Abilities,  Next: Compiler Options,  Prev: Language Extensions,  Up: Advantages Over f2c

14.1.2 Diagnostic Abilities
---------------------------

`g77' offers better diagnosis of problems in `FORMAT' statements.
`f2c' doesn't, for example, emit any diagnostic for
`FORMAT(XZFAJG10324)', leaving that to be diagnosed, at run time, by
the `libf2c' run-time library.


File: g77.info,  Node: Compiler Options,  Next: Compiler Speed,  Prev: Diagnostic Abilities,  Up: Advantages Over f2c

14.1.3 Compiler Options
-----------------------

`g77' offers compiler options that `f2c' doesn't, most of which are
designed to more easily accommodate legacy code:

   * Two that control the automatic appending of extra underscores to
     external names

   * One that allows dollar signs (`$') in symbol names

   * A variety that control acceptance of various "ugly" constructs

   * Several that specify acceptable use of upper and lower case in the
     source code

   * Many that enable, disable, delete, or hide groups of intrinsics

   * One to specify the length of fixed-form source lines (normally 72)

   * One to specify the the source code is written in Fortran-90-style
     free-form

   However, `f2c' offers a few that `g77' doesn't, like an option to
have `REAL' default to `REAL*8'.  It is expected that `g77' will offer
all of the missing options pertinent to being a Fortran compiler at
some time in the future.


File: g77.info,  Node: Compiler Speed,  Next: Program Speed,  Prev: Compiler Options,  Up: Advantages Over f2c

14.1.4 Compiler Speed
---------------------

Saving the steps of writing and then rereading C code is a big reason
why `g77' should be able to compile code much faster than using `f2c'
in conjunction with the equivalent invocation of `gcc'.

   However, due to `g77''s youth, lots of self-checking is still being
performed.  As a result, this improvement is as yet unrealized (though
the potential seems to be there for quite a big speedup in the future).
It is possible that, as of version 0.5.18, `g77' is noticeably faster
compiling many Fortran source files than using `f2c' in conjunction
with `gcc'.


File: g77.info,  Node: Program Speed,  Next: Ease of Debugging,  Prev: Compiler Speed,  Up: Advantages Over f2c

14.1.5 Program Speed
--------------------

`g77' has the potential to better optimize code than `f2c', even when
`gcc' is used to compile the output of `f2c', because `f2c' must
necessarily translate Fortran into a somewhat lower-level language (C)
that cannot preserve all the information that is potentially useful for
optimization, while `g77' can gather, preserve, and transmit that
information directly to the GBE.

   For example, `g77' implements `ASSIGN' and assigned `GOTO' using
direct assignment of pointers to labels and direct jumps to labels,
whereas `f2c' maps the assigned labels to integer values and then uses
a C `switch' statement to encode the assigned `GOTO' statements.

   However, as is typical, theory and reality don't quite match, at
least not in all cases, so it is still the case that `f2c' plus `gcc'
can generate code that is faster than `g77'.

   Version 0.5.18 of `g77' offered default settings and options, via
patches to the `gcc' back end, that allow for better program speed,
though some of these improvements also affected the performance of
programs translated by `f2c' and then compiled by `g77''s version of
`gcc'.

   Version 0.5.20 of `g77' offers further performance improvements, at
least one of which (alias analysis) is not generally applicable to
`f2c' (though `f2c' could presumably be changed to also take advantage
of this new capability of the `gcc' back end, assuming this is made
available in an upcoming release of `gcc').


File: g77.info,  Node: Ease of Debugging,  Next: Character and Hollerith Constants,  Prev: Program Speed,  Up: Advantages Over f2c

14.1.6 Ease of Debugging
------------------------

Because `g77' compiles directly to assembler code like `gcc', instead
of translating to an intermediate language (C) as does `f2c', support
for debugging can be better for `g77' than `f2c'.

   However, although `g77' might be somewhat more "native" in terms of
debugging support than `f2c' plus `gcc', there still are a lot of
things "not quite right".  Many of the important ones should be
resolved in the near future.

   For example, `g77' doesn't have to worry about reserved names like
`f2c' does.  Given `FOR = WHILE', `f2c' must necessarily translate this
to something _other_ than `for = while;', because C reserves those
words.

   However, `g77' does still uses things like an extra level of
indirection for `ENTRY'-laden procedures--in this case, because the
back end doesn't yet support multiple entry points.

   Another example is that, given

     COMMON A, B
     EQUIVALENCE (B, C)

the `g77' user should be able to access the variables directly, by name,
without having to traverse C-like structures and unions, while `f2c' is
unlikely to ever offer this ability (due to limitations in the C
language).

   However, due to apparent bugs in the back end, `g77' currently
doesn't take advantage of this facility at all--it doesn't emit any
debugging information for `COMMON' and `EQUIVALENCE' areas, other than
information on the array of `char' it creates (and, in the case of
local `EQUIVALENCE', names) for each such area.

   Yet another example is arrays.  `g77' represents them to the debugger
using the same "dimensionality" as in the source code, while `f2c' must
necessarily convert them all to one-dimensional arrays to fit into the
confines of the C language.  However, the level of support offered by
debuggers for interactive Fortran-style access to arrays as compiled by
`g77' can vary widely.  In some cases, it can actually be an advantage
that `f2c' converts everything to widely supported C semantics.

   In fairness, `g77' could do many of the things `f2c' does to get
things working at least as well as `f2c'--for now, the developers
prefer making `g77' work the way they think it is supposed to, and
finding help improving the other products (the back end of `gcc';
`gdb'; and so on) to get things working properly.


File: g77.info,  Node: Character and Hollerith Constants,  Prev: Ease of Debugging,  Up: Advantages Over f2c

14.1.7 Character and Hollerith Constants
----------------------------------------

To avoid the extensive hassle that would be needed to avoid this, `f2c'
uses C character constants to encode character and Hollerith constants.
That means a constant like `'HELLO'' is translated to `"hello"' in C,
which further means that an extra null byte is present at the end of
the constant.  This null byte is superfluous.

   `g77' does not generate such null bytes.  This represents significant
savings of resources, such as on systems where `/dev/null' or
`/dev/zero' represent bottlenecks in the systems' performance, because
`g77' simply asks for fewer zeros from the operating system than `f2c'.
(Avoiding spurious use of zero bytes, each byte typically have eight
zero bits, also reduces the liabilities in case Microsoft's rumored
patent on the digits 0 and 1 is upheld.)


File: g77.info,  Node: Block Data and Libraries,  Next: Loops,  Prev: Advantages Over f2c,  Up: Collected Fortran Wisdom

14.2 Block Data and Libraries
=============================

To ensure that block data program units are linked, especially a concern
when they are put into libraries, give each one a name (as in `BLOCK
DATA FOO') and make sure there is an `EXTERNAL FOO' statement in every
program unit that uses any common block initialized by the
corresponding `BLOCK DATA'.  `g77' currently compiles a `BLOCK DATA' as
if it were a `SUBROUTINE', that is, it generates an actual procedure
having the appropriate name.  The procedure does nothing but return
immediately if it happens to be called.  For `EXTERNAL FOO', where
`FOO' is not otherwise referenced in the same program unit, `g77'
assumes there exists a `BLOCK DATA FOO' in the program and ensures that
by generating a reference to it so the linker will make sure it is
present.  (Specifically, `g77' outputs in the data section a static
pointer to the external name `FOO'.)

   The implementation `g77' currently uses to make this work is one of
the few things not compatible with `f2c' as currently shipped.  `f2c'
currently does nothing with `EXTERNAL FOO' except issue a warning that
`FOO' is not otherwise referenced, and, for `BLOCK DATA FOO', `f2c'
doesn't generate a dummy procedure with the name `FOO'.  The upshot is
that you shouldn't mix `f2c' and `g77' in this particular case.  If you
use `f2c' to compile `BLOCK DATA FOO', then any `g77'-compiled program
unit that says `EXTERNAL FOO' will result in an unresolved reference
when linked.  If you do the opposite, then `FOO' might not be linked in
under various circumstances (such as when `FOO' is in a library, or
you're using a "clever" linker--so clever, it produces a broken program
with little or no warning by omitting initializations of global data
because they are contained in unreferenced procedures).

   The changes you make to your code to make `g77' handle this
situation, however, appear to be a widely portable way to handle it.
That is, many systems permit it (as they should, since the FORTRAN 77
standard permits `EXTERNAL FOO' when `FOO' is a block data program
unit), and of the ones that might not link `BLOCK DATA FOO' under some
circumstances, most of them appear to do so once `EXTERNAL FOO' is
present in the appropriate program units.

   Here is the recommended approach to modifying a program containing a
program unit such as the following:

     BLOCK DATA FOO
     COMMON /VARS/ X, Y, Z
     DATA X, Y, Z / 3., 4., 5. /
     END

If the above program unit might be placed in a library module, then
ensure that every program unit in every program that references that
particular `COMMON' area uses the `EXTERNAL' statement to force the
area to be initialized.

   For example, change a program unit that starts with

     INTEGER FUNCTION CURX()
     COMMON /VARS/ X, Y, Z
     CURX = X
     END

so that it uses the `EXTERNAL' statement, as in:

     INTEGER FUNCTION CURX()
     COMMON /VARS/ X, Y, Z
     EXTERNAL FOO
     CURX = X
     END

That way, `CURX' is compiled by `g77' (and many other compilers) so
that the linker knows it must include `FOO', the `BLOCK DATA' program
unit that sets the initial values for the variables in `VAR', in the
executable program.


File: g77.info,  Node: Loops,  Next: Working Programs,  Prev: Block Data and Libraries,  Up: Collected Fortran Wisdom

14.3 Loops
==========

The meaning of a `DO' loop in Fortran is precisely specified in the
Fortran standard...and is quite different from what many programmers
might expect.

   In particular, Fortran iterative `DO' loops are implemented as if
the number of trips through the loop is calculated _before_ the loop is
entered.

   The number of trips for a loop is calculated from the START, END,
and INCREMENT values specified in a statement such as:

     DO ITER = START, END, INCREMENT

The trip count is evaluated using a fairly simple formula based on the
three values following the `=' in the statement, and it is that trip
count that is effectively decremented during each iteration of the loop.
If, at the beginning of an iteration of the loop, the trip count is
zero or negative, the loop terminates.  The per-loop-iteration
modifications to ITER are not related to determining whether to
terminate the loop.

   There are two important things to remember about the trip count:

   * It can be _negative_, in which case it is treated as if it was
     zero--meaning the loop is not executed at all.

   * The type used to _calculate_ the trip count is the same type as
     ITER, but the final calculation, and thus the type of the trip
     count itself, always is `INTEGER(KIND=1)'.

   These two items mean that there are loops that cannot be written in
straightforward fashion using the Fortran `DO'.

   For example, on a system with the canonical 32-bit two's-complement
implementation of `INTEGER(KIND=1)', the following loop will not work:

     DO I = -2000000000, 2000000000

Although the START and END values are well within the range of
`INTEGER(KIND=1)', the _trip count_ is not.  The expected trip count is
40000000001, which is outside the range of `INTEGER(KIND=1)' on many
systems.

   Instead, the above loop should be constructed this way:

     I = -2000000000
     DO
       IF (I .GT. 2000000000) EXIT
       ...
       I = I + 1
     END DO

The simple `DO' construct and the `EXIT' statement (used to leave the
innermost loop) are F90 features that `g77' supports.

   Some Fortran compilers have buggy implementations of `DO', in that
they don't follow the standard.  They implement `DO' as a
straightforward translation to what, in C, would be a `for' statement.
Instead of creating a temporary variable to hold the trip count as
calculated at run time, these compilers use the iteration variable ITER
to control whether the loop continues at each iteration.

   The bug in such an implementation shows up when the trip count is
within the range of the type of ITER, but the magnitude of `ABS(END) +
ABS(INCR)' exceeds that range.  For example:

     DO I = 2147483600, 2147483647

A loop started by the above statement will work as implemented by
`g77', but the use, by some compilers, of a more C-like implementation
akin to

     for (i = 2147483600; i <= 2147483647; ++i)

produces a loop that does not terminate, because `i' can never be
greater than 2147483647, since incrementing it beyond that value
overflows `i', setting it to -2147483648.  This is a large, negative
number that still is less than 2147483647.

   Another example of unexpected behavior of `DO' involves using a
nonintegral iteration variable ITER, that is, a `REAL' variable.
Consider the following program:

           DATA BEGIN, END, STEP /.1, .31, .007/
           DO 10 R = BEGIN, END, STEP
              IF (R .GT. END) PRINT *, R, ' .GT. ', END, '!!'
              PRINT *,R
     10    CONTINUE
           PRINT *,'LAST = ',R
           IF (R .LE. END) PRINT *, R, ' .LE. ', END, '!!'
           END

A C-like view of `DO' would hold that the two "exclamatory" `PRINT'
statements are never executed.  However, this is the output of running
the above program as compiled by `g77' on a GNU/Linux ix86 system:

      .100000001
      .107000001
      .114
      .120999999
      ...
      .289000005
      .296000004
      .303000003
     LAST =   .310000002
      .310000002 .LE.   .310000002!!

   Note that one of the two checks in the program turned up an apparent
violation of the programmer's expectation--yet, the loop is correctly
implemented by `g77', in that it has 30 iterations.  This trip count of
30 is correct when evaluated using the floating-point representations
for the BEGIN, END, and INCR values (.1, .31, .007) on GNU/Linux ix86
are used.  On other systems, an apparently more accurate trip count of
31 might result, but, nevertheless, `g77' is faithfully following the
Fortran standard, and the result is not what the author of the sample
program above apparently expected.  (Such other systems might, for
different values in the `DATA' statement, violate the other
programmer's expectation, for example.)

   Due to this combination of imprecise representation of
floating-point values and the often-misunderstood interpretation of
`DO' by standard-conforming compilers such as `g77', use of `DO' loops
with `REAL' iteration variables is not recommended.  Such use can be
caught by specifying `-Wsurprising'.  *Note Warning Options::, for more
information on this option.


File: g77.info,  Node: Working Programs,  Next: Overly Convenient Options,  Prev: Loops,  Up: Collected Fortran Wisdom

14.4 Working Programs
=====================

Getting Fortran programs to work in the first place can be quite a
challenge--even when the programs already work on other systems, or
when using other compilers.

   `g77' offers some facilities that might be useful for tracking down
bugs in such programs.

* Menu:

* Not My Type::
* Variables Assumed To Be Zero::
* Variables Assumed To Be Saved::
* Unwanted Variables::
* Unused Arguments::
* Surprising Interpretations of Code::
* Aliasing Assumed To Work::
* Output Assumed To Flush::
* Large File Unit Numbers::
* Floating-point precision::
* Inconsistent Calling Sequences::


File: g77.info,  Node: Not My Type,  Next: Variables Assumed To Be Zero,  Up: Working Programs

14.4.1 Not My Type
------------------

A fruitful source of bugs in Fortran source code is use, or mis-use, of
Fortran's implicit-typing feature, whereby the type of a variable,
array, or function is determined by the first character of its name.

   Simple cases of this include statements like `LOGX=9.227', without a
statement such as `REAL LOGX'.  In this case, `LOGX' is implicitly
given `INTEGER(KIND=1)' type, with the result of the assignment being
that it is given the value `9'.

   More involved cases include a function that is defined starting with
a statement like `DOUBLE PRECISION FUNCTION IPS(...)'.  Any caller of
this function that does not also declare `IPS' as type `DOUBLE
PRECISION' (or, in GNU Fortran, `REAL(KIND=2)') is likely to assume it
returns `INTEGER', or some other type, leading to invalid results or
even program crashes.

   The `-Wimplicit' option might catch failures to properly specify the
types of variables, arrays, and functions in the code.

   However, in code that makes heavy use of Fortran's implicit-typing
facility, this option might produce so many warnings about cases that
are working, it would be hard to find the one or two that represent
bugs.  This is why so many experienced Fortran programmers strongly
recommend widespread use of the `IMPLICIT NONE' statement, despite it
not being standard FORTRAN 77, to completely turn off implicit typing.
(`g77' supports `IMPLICIT NONE', as do almost all FORTRAN 77 compilers.)

   Note that `-Wimplicit' catches only implicit typing of _names_.  It
does not catch implicit typing of expressions such as `X**(2/3)'.  Such
expressions can be buggy as well--in fact, `X**(2/3)' is equivalent to
`X**0', due to the way Fortran expressions are given types and then
evaluated.  (In this particular case, the programmer probably wanted
`X**(2./3.)'.)


File: g77.info,  Node: Variables Assumed To Be Zero,  Next: Variables Assumed To Be Saved,  Prev: Not My Type,  Up: Working Programs

14.4.2 Variables Assumed To Be Zero
-----------------------------------

Many Fortran programs were developed on systems that provided automatic
initialization of all, or some, variables and arrays to zero.  As a
result, many of these programs depend, sometimes inadvertently, on this
behavior, though to do so violates the Fortran standards.

   You can ask `g77' for this behavior by specifying the
`-finit-local-zero' option when compiling Fortran code.  (You might
want to specify `-fno-automatic' as well, to avoid code-size inflation
for non-optimized compilations.)

   Note that a program that works better when compiled with the
`-finit-local-zero' option is almost certainly depending on a
particular system's, or compiler's, tendency to initialize some
variables to zero.  It might be worthwhile finding such cases and
fixing them, using techniques such as compiling with the `-O
-Wuninitialized' options using `g77'.


File: g77.info,  Node: Variables Assumed To Be Saved,  Next: Unwanted Variables,  Prev: Variables Assumed To Be Zero,  Up: Working Programs

14.4.3 Variables Assumed To Be Saved
------------------------------------

Many Fortran programs were developed on systems that saved the values
of all, or some, variables and arrays across procedure calls.  As a
result, many of these programs depend, sometimes inadvertently, on
being able to assign a value to a variable, perform a `RETURN' to a
calling procedure, and, upon subsequent invocation, reference the
previously assigned variable to obtain the value.

   They expect this despite not using the `SAVE' statement to specify
that the value in a variable is expected to survive procedure returns
and calls.  Depending on variables and arrays to retain values across
procedure calls without using `SAVE' to require it violates the Fortran
standards.

   You can ask `g77' to assume `SAVE' is specified for all relevant
(local) variables and arrays by using the `-fno-automatic' option.

   Note that a program that works better when compiled with the
`-fno-automatic' option is almost certainly depending on not having to
use the `SAVE' statement as required by the Fortran standard.  It might
be worthwhile finding such cases and fixing them, using techniques such
as compiling with the `-O -Wuninitialized' options using `g77'.


File: g77.info,  Node: Unwanted Variables,  Next: Unused Arguments,  Prev: Variables Assumed To Be Saved,  Up: Working Programs

14.4.4 Unwanted Variables
-------------------------

The `-Wunused' option can find bugs involving implicit typing, sometimes
more easily than using `-Wimplicit' in code that makes heavy use of
implicit typing.  An unused variable or array might indicate that the
spelling for its declaration is different from that of its intended
uses.

   Other than cases involving typos, unused variables rarely indicate
actual bugs in a program.  However, investigating such cases thoroughly
has, on occasion, led to the discovery of code that had not been
completely written--where the programmer wrote declarations as needed
for the whole algorithm, wrote some or even most of the code for that
algorithm, then got distracted and forgot that the job was not complete.


File: g77.info,  Node: Unused Arguments,  Next: Surprising Interpretations of Code,  Prev: Unwanted Variables,  Up: Working Programs

14.4.5 Unused Arguments
-----------------------

As with unused variables, It is possible that unused arguments to a
procedure might indicate a bug.  Compile with `-W -Wunused' option to
catch cases of unused arguments.

   Note that `-W' also enables warnings regarding overflow of
floating-point constants under certain circumstances.


File: g77.info,  Node: Surprising Interpretations of Code,  Next: Aliasing Assumed To Work,  Prev: Unused Arguments,  Up: Working Programs

14.4.6 Surprising Interpretations of Code
-----------------------------------------

The `-Wsurprising' option can help find bugs involving expression
evaluation or in the way `DO' loops with non-integral iteration
variables are handled.  Cases found by this option might indicate a
difference of interpretation between the author of the code involved,
and a standard-conforming compiler such as `g77'.  Such a difference
might produce actual bugs.

   In any case, changing the code to explicitly do what the programmer
might have expected it to do, so `g77' and other compilers are more
likely to follow the programmer's expectations, might be worthwhile,
especially if such changes make the program work better.


File: g77.info,  Node: Aliasing Assumed To Work,  Next: Output Assumed To Flush,  Prev: Surprising Interpretations of Code,  Up: Working Programs

14.4.7 Aliasing Assumed To Work
-------------------------------

The `-falias-check', `-fargument-alias', `-fargument-noalias', and
`-fno-argument-noalias-global' options, introduced in version 0.5.20 and
`g77''s version 2.7.2.2.f.2 of `gcc', were withdrawn as of `g77'
version 0.5.23 due to their not being supported by `gcc' version 2.8.

   These options control the assumptions regarding aliasing
(overlapping) of writes and reads to main memory (core) made by the
`gcc' back end.

   The information below still is useful, but applies to only those
versions of `g77' that support the alias analysis implied by support
for these options.

   These options are effective only when compiling with `-O'
(specifying any level other than `-O0') or with `-falias-check'.

   The default for Fortran code is `-fargument-noalias-global'.  (The
default for C code and code written in other C-based languages is
`-fargument-alias'.  These defaults apply regardless of whether you use
`g77' or `gcc' to compile your code.)

   Note that, on some systems, compiling with `-fforce-addr' in effect
can produce more optimal code when the default aliasing options are in
effect (and when optimization is enabled).

   If your program is not working when compiled with optimization, it
is possible it is violating the Fortran standards (77 and 90) by
relying on the ability to "safely" modify variables and arrays that are
aliased, via procedure calls, to other variables and arrays, without
using `EQUIVALENCE' to explicitly set up this kind of aliasing.

   (The FORTRAN 77 standard's prohibition of this sort of overlap,
generally referred to therein as "storage association", appears in
Sections 15.9.3.6.  This prohibition allows implementations, such as
`g77', to, for example, implement the passing of procedures and even
values in `COMMON' via copy operations into local, perhaps more
efficiently accessed temporaries at entry to a procedure, and, where
appropriate, via copy operations back out to their original locations
in memory at exit from that procedure, without having to take into
consideration the order in which the local copies are updated by the
code, among other things.)

   To test this hypothesis, try compiling your program with the
`-fargument-alias' option, which causes the compiler to revert to
assumptions essentially the same as made by versions of `g77' prior to
0.5.20.

   If the program works using this option, that strongly suggests that
the bug is in your program.  Finding and fixing the bug(s) should
result in a program that is more standard-conforming and that can be
compiled by `g77' in a way that results in a faster executable.

   (You might want to try compiling with `-fargument-noalias', a kind
of half-way point, to see if the problem is limited to aliasing between
dummy arguments and `COMMON' variables--this option assumes that such
aliasing is not done, while still allowing aliasing among dummy
arguments.)

   An example of aliasing that is invalid according to the standards is
shown in the following program, which might _not_ produce the expected
results when executed:

     I = 1
     CALL FOO(I, I)
     PRINT *, I
     END

     SUBROUTINE FOO(J, K)
     J = J + K
     K = J * K
     PRINT *, J, K
     END

   The above program attempts to use the temporary aliasing of the `J'
and `K' arguments in `FOO' to effect a pathological behavior--the
simultaneous changing of the values of _both_ `J' and `K' when either
one of them is written.

   The programmer likely expects the program to print these values:

     2  4
     4

   However, since the program is not standard-conforming, an
implementation's behavior when running it is undefined, because
subroutine `FOO' modifies at least one of the arguments, and they are
aliased with each other.  (Even if one of the assignment statements was
deleted, the program would still violate these rules.  This kind of
on-the-fly aliasing is permitted by the standard only when none of the
aliased items are defined, or written, while the aliasing is in effect.)

   As a practical example, an optimizing compiler might schedule the `J
=' part of the second line of `FOO' _after_ the reading of `J' and `K'
for the `J * K' expression, resulting in the following output:

     2  2
     2

   Essentially, compilers are promised (by the standard and, therefore,
by programmers who write code they claim to be standard-conforming)
that if they cannot detect aliasing via static analysis of a single
program unit's `EQUIVALENCE' and `COMMON' statements, no such aliasing
exists.  In such cases, compilers are free to assume that an assignment
to one variable will not change the value of another variable, allowing
it to avoid generating code to re-read the value of the other variable,
to re-schedule reads and writes, and so on, to produce a faster
executable.

   The same promise holds true for arrays (as seen by the called
procedure)--an element of one dummy array cannot be aliased with, or
overlap, any element of another dummy array or be in a `COMMON' area
known to the procedure.

   (These restrictions apply only when the procedure defines, or writes
to, one of the aliased variables or arrays.)

   Unfortunately, there is no way to find _all_ possible cases of
violations of the prohibitions against aliasing in Fortran code.
Static analysis is certainly imperfect, as is run-time analysis, since
neither can catch all violations.  (Static analysis can catch all
likely violations, and some that might never actually happen, while
run-time analysis can catch only those violations that actually happen
during a particular run.  Neither approach can cope with programs
mixing Fortran code with routines written in other languages, however.)

   Currently, `g77' provides neither static nor run-time facilities to
detect any cases of this problem, although other products might.
Run-time facilities are more likely to be offered by future versions of
`g77', though patches improving `g77' so that it provides either form
of detection are welcome.


File: g77.info,  Node: Output Assumed To Flush,  Next: Large File Unit Numbers,  Prev: Aliasing Assumed To Work,  Up: Working Programs

14.4.8 Output Assumed To Flush
------------------------------

For several versions prior to 0.5.20, `g77' configured its version of
the `libf2c' run-time library so that one of its configuration macros,
`ALWAYS_FLUSH', was defined.

   This was done as a result of a belief that many programs expected
output to be flushed to the operating system (under UNIX, via the
`fflush()' library call) with the result that errors, such as disk
full, would be immediately flagged via the relevant `ERR=' and
`IOSTAT=' mechanism.

   Because of the adverse effects this approach had on the performance
of many programs, `g77' no longer configures `libf2c' (now named
`libg2c' in its `g77' incarnation) to always flush output.

   If your program depends on this behavior, either insert the
appropriate `CALL FLUSH' statements, or modify the sources to the
`libg2c', rebuild and reinstall `g77', and relink your programs with
the modified library.

   (Ideally, `libg2c' would offer the choice at run-time, so that a
compile-time option to `g77' or `f2c' could result in generating the
appropriate calls to flushing or non-flushing library routines.)

   Some Fortran programs require output (writes) to be flushed to the
operating system (under UNIX, via the `fflush()' library call) so that
errors, such as disk full, are immediately flagged via the relevant
`ERR=' and `IOSTAT=' mechanism, instead of such errors being flagged
later as subsequent writes occur, forcing the previously written data
to disk, or when the file is closed.

   Essentially, the difference can be viewed as synchronous error
reporting (immediate flagging of errors during writes) versus
asynchronous, or, more precisely, buffered error reporting (detection
of errors might be delayed).

   `libg2c' supports flagging write errors immediately when it is built
with the `ALWAYS_FLUSH' macro defined.  This results in a `libg2c' that
runs slower, sometimes quite a bit slower, under certain
circumstances--for example, accessing files via the networked file
system NFS--but the effect can be more reliable, robust file I/O.

   If you know that Fortran programs requiring this level of precision
of error reporting are to be compiled using the version of `g77' you
are building, you might wish to modify the `g77' source tree so that
the version of `libg2c' is built with the `ALWAYS_FLUSH' macro defined,
enabling this behavior.

   To do this, find this line in `gcc/libf2c/f2c.h' in your `g77'
source tree:

     /* #define ALWAYS_FLUSH */

   Remove the leading `/* ', so the line begins with `#define', and the
trailing ` */'.

   Then build or rebuild `g77' as appropriate.


File: g77.info,  Node: Large File Unit Numbers,  Next: Floating-point precision,  Prev: Output Assumed To Flush,  Up: Working Programs

14.4.9 Large File Unit Numbers
------------------------------

If your program crashes at run time with a message including the text
`illegal unit number', that probably is a message from the run-time
library, `libg2c'.

   The message means that your program has attempted to use a file unit
number that is out of the range accepted by `libg2c'.  Normally, this
range is 0 through 99, and the high end of the range is controlled by a
`libg2c' source-file macro named `MXUNIT'.

   If you can easily change your program to use unit numbers in the
range 0 through 99, you should do so.

   As distributed, whether as part of `f2c' or `g77', `libf2c' accepts
file unit numbers only in the range 0 through 99.  For example, a
statement such as `WRITE (UNIT=100)' causes a run-time crash in
`libf2c', because the unit number, 100, is out of range.

   If you know that Fortran programs at your installation require the
use of unit numbers higher than 99, you can change the value of the
`MXUNIT' macro, which represents the maximum unit number, to an
appropriately higher value.

   To do this, edit the file `gcc/libf2c/libI77/fio.h' in your `g77'
source tree, changing the following line:

     #define MXUNIT 100

   Change the line so that the value of `MXUNIT' is defined to be at
least one _greater_ than the maximum unit number used by the Fortran
programs on your system.

   (For example, a program that does `WRITE (UNIT=255)' would require
`MXUNIT' set to at least 256 to avoid crashing.)

   Then build or rebuild `g77' as appropriate.

   _Note:_ Changing this macro has _no_ effect on other limits your
system might place on the number of files open at the same time.  That
is, the macro might allow a program to do `WRITE (UNIT=100)', but the
library and operating system underlying `libf2c' might disallow it if
many other files have already been opened (via `OPEN' or implicitly via
`READ', `WRITE', and so on).  Information on how to increase these
other limits should be found in your system's documentation.


File: g77.info,  Node: Floating-point precision,  Next: Inconsistent Calling Sequences,  Prev: Large File Unit Numbers,  Up: Working Programs

14.4.10 Floating-point precision
--------------------------------

If your program depends on exact IEEE 754 floating-point handling it may
help on some systems--specifically x86 or m68k hardware--to use the
`-ffloat-store' option or to reset the precision flag on the
floating-point unit.  *Note Optimize Options::.

   However, it might be better simply to put the FPU into double
precision mode and not take the performance hit of `-ffloat-store'.  On
x86 and m68k GNU systems you can do this with a technique similar to
that for turning on floating-point exceptions (*note Floating-point
Exception Handling::).  The control word could be set to double
precision by some code like this one:
     #include <fpu_control.h>
     {
       fpu_control_t cw = (_FPU_DEFAULT & ~_FPU_EXTENDED) | _FPU_DOUBLE;
       _FPU_SETCW(cw);
     }
   (It is not clear whether this has any effect on the operation of the
GNU maths library, but we have no evidence of it causing trouble.)

   Some targets (such as the Alpha) may need special options for full
IEEE conformance.  *Note Hardware Models and Configurations:
(gcc)Submodel Options.


File: g77.info,  Node: Inconsistent Calling Sequences,  Prev: Floating-point precision,  Up: Working Programs

14.4.11 Inconsistent Calling Sequences
--------------------------------------

Code containing inconsistent calling sequences in the same file is
normally rejected--see *Note GLOBALS::.  (Use, say, `ftnchek' to ensure
consistency across source files.  *Note Generating Skeletons and
Prototypes with `f2c': f2c Skeletons and Prototypes.)

   Mysterious errors, which may appear to be code generation problems,
can appear specifically on the x86 architecture with some such
inconsistencies.  On x86 hardware, floating-point return values of
functions are placed on the floating-point unit's register stack, not
the normal stack.  Thus calling a `REAL' or `DOUBLE PRECISION'
`FUNCTION' as some other sort of procedure, or vice versa, scrambles
the floating-point stack.  This may break unrelated code executed
later.  Similarly if, say, external C routines are written incorrectly.


File: g77.info,  Node: Overly Convenient Options,  Next: Faster Programs,  Prev: Working Programs,  Up: Collected Fortran Wisdom

14.5 Overly Convenient Command-line Options
===========================================

These options should be used only as a quick-and-dirty way to determine
how well your program will run under different compilation models
without having to change the source.  Some are more problematic than
others, depending on how portable and maintainable you want the program
to be (and, of course, whether you are allowed to change it at all is
crucial).

   You should not continue to use these command-line options to compile
a given program, but rather should make changes to the source code:

`-finit-local-zero'
     (This option specifies that any uninitialized local variables and
     arrays have default initialization to binary zeros.)

     Many other compilers do this automatically, which means lots of
     Fortran code developed with those compilers depends on it.

     It is safer (and probably would produce a faster program) to find
     the variables and arrays that need such initialization and provide
     it explicitly via `DATA', so that `-finit-local-zero' is not
     needed.

     Consider using `-Wuninitialized' (which requires `-O') to find
     likely candidates, but do not specify `-finit-local-zero' or
     `-fno-automatic', or this technique won't work.

`-fno-automatic'
     (This option specifies that all local variables and arrays are to
     be treated as if they were named in `SAVE' statements.)

     Many other compilers do this automatically, which means lots of
     Fortran code developed with those compilers depends on it.

     The effect of this is that all non-automatic variables and arrays
     are made static, that is, not placed on the stack or in heap
     storage.  This might cause a buggy program to appear to work
     better.  If so, rather than relying on this command-line option
     (and hoping all compilers provide the equivalent one), add `SAVE'
     statements to some or all program unit sources, as appropriate.
     Consider using `-Wuninitialized' (which requires `-O') to find
     likely candidates, but do not specify `-finit-local-zero' or
     `-fno-automatic', or this technique won't work.

     The default is `-fautomatic', which tells `g77' to try and put
     variables and arrays on the stack (or in fast registers) where
     possible and reasonable.  This tends to make programs faster.

     _Note:_ Automatic variables and arrays are not affected by this
     option.  These are variables and arrays that are _necessarily_
     automatic, either due to explicit statements, or due to the way
     they are declared.  Examples include local variables and arrays
     not given the `SAVE' attribute in procedures declared `RECURSIVE',
     and local arrays declared with non-constant bounds (automatic
     arrays).  Currently, `g77' supports only automatic arrays, not
     `RECURSIVE' procedures or other means of explicitly specifying
     that variables or arrays are automatic.

`-fGROUP-intrinsics-hide'
     Change the source code to use `EXTERNAL' for any external procedure
     that might be the name of an intrinsic.  It is easy to find these
     using `-fGROUP-intrinsics-disable'.


File: g77.info,  Node: Faster Programs,  Prev: Overly Convenient Options,  Up: Collected Fortran Wisdom

14.6 Faster Programs
====================

Aside from the usual `gcc' options, such as `-O', `-ffast-math', and so
on, consider trying some of the following approaches to speed up your
program (once you get it working).

* Menu:

* Aligned Data::
* Prefer Automatic Uninitialized Variables::
* Avoid f2c Compatibility::
* Use Submodel Options::


File: g77.info,  Node: Aligned Data,  Next: Prefer Automatic Uninitialized Variables,  Up: Faster Programs

14.6.1 Aligned Data
-------------------

On some systems, such as those with Pentium Pro CPUs, programs that
make heavy use of `REAL(KIND=2)' (`DOUBLE PRECISION') might run much
slower than possible due to the compiler not aligning these 64-bit
values to 64-bit boundaries in memory.  (The effect also is present,
though to a lesser extent, on the 586 (Pentium) architecture.)

   The Intel x86 architecture generally ensures that these programs will
work on all its implementations, but particular implementations (such
as Pentium Pro) perform better with more strict alignment.  (Such
behavior isn't unique to the Intel x86 architecture.)  Other
architectures might _demand_ 64-bit alignment of 64-bit data.

   There are a variety of approaches to use to address this problem:

   * Order your `COMMON' and `EQUIVALENCE' areas such that the
     variables and arrays with the widest alignment guidelines come
     first.

     For example, on most systems, this would mean placing
     `COMPLEX(KIND=2)', `REAL(KIND=2)', and `INTEGER(KIND=2)' entities
     first, followed by `REAL(KIND=1)', `INTEGER(KIND=1)', and
     `LOGICAL(KIND=1)' entities, then `INTEGER(KIND=6)' entities, and
     finally `CHARACTER' and `INTEGER(KIND=3)' entities.

     The reason to use such placement is it makes it more likely that
     your data will be aligned properly, without requiring you to do
     detailed analysis of each aggregate (`COMMON' and `EQUIVALENCE')
     area.

     Specifically, on systems where the above guidelines are
     appropriate, placing `CHARACTER' entities before `REAL(KIND=2)'
     entities can work just as well, but only if the number of bytes
     occupied by the `CHARACTER' entities is divisible by the
     recommended alignment for `REAL(KIND=2)'.

     By ordering the placement of entities in aggregate areas according
     to the simple guidelines above, you avoid having to carefully
     count the number of bytes occupied by each entity to determine
     whether the actual alignment of each subsequent entity meets the
     alignment guidelines for the type of that entity.

     If you don't ensure correct alignment of `COMMON' elements, the
     compiler may be forced by some systems to violate the Fortran
     semantics by adding padding to get `DOUBLE PRECISION' data
     properly aligned.  If the unfortunate practice is employed of
     overlaying different types of data in the `COMMON' block, the
     different variants of this block may become misaligned with
     respect to each other.  Even if your platform doesn't require
     strict alignment, `COMMON' should be laid out as above for
     portability.  (Unfortunately the FORTRAN 77 standard didn't
     anticipate this possible requirement, which is
     compiler-independent on a given platform.)

   * Use the (x86-specific) `-malign-double' option when compiling
     programs for the Pentium and Pentium Pro architectures (called 586
     and 686 in the `gcc' configuration subsystem).  The warning about
     this in the `gcc' manual isn't generally relevant to Fortran, but
     using it will force `COMMON' to be padded if necessary to align
     `DOUBLE PRECISION' data.

     When `DOUBLE PRECISION' data is forcibly aligned in `COMMON' by
     `g77' due to specifying `-malign-double', `g77' issues a warning
     about the need to insert padding.

     In this case, each and every program unit that uses the same
     `COMMON' area must specify the same layout of variables and their
     types for that area and be compiled with `-malign-double' as well.
     `g77' will issue warnings in each case, but as long as every
     program unit using that area is compiled with the same warnings,
     the resulting object files should work when linked together unless
     the program makes additional assumptions about `COMMON' area
     layouts that are outside the scope of the FORTRAN 77 standard, or
     uses `EQUIVALENCE' or different layouts in ways that assume no
     padding is ever inserted by the compiler.

   * Ensure that `crt0.o' or `crt1.o' on your system guarantees a 64-bit
     aligned stack for `main()'.  The recent one from GNU (`glibc2')
     will do this on x86 systems, but we don't know of any other x86
     setups where it will be right.  Read your system's documentation
     to determine if it is appropriate to upgrade to a more recent
     version to obtain the optimal alignment.

   Progress is being made on making this work "out of the box" on
future versions of `g77', `gcc', and some of the relevant operating
systems (such as GNU/Linux).


File: g77.info,  Node: Prefer Automatic Uninitialized Variables,  Next: Avoid f2c Compatibility,  Prev: Aligned Data,  Up: Faster Programs

14.6.2 Prefer Automatic Uninitialized Variables
-----------------------------------------------

If you're using `-fno-automatic' already, you probably should change
your code to allow compilation with `-fautomatic' (the default), to
allow the program to run faster.

   Similarly, you should be able to use `-fno-init-local-zero' (the
default) instead of `-finit-local-zero'.  This is because it is rare
that every variable affected by these options in a given program
actually needs to be so affected.

   For example, `-fno-automatic', which effectively `SAVE's every local
non-automatic variable and array, affects even things like `DO'
iteration variables, which rarely need to be `SAVE'd, and this often
reduces run-time performances.  Similarly, `-fno-init-local-zero'
forces such variables to be initialized to zero--when `SAVE'd (such as
when `-fno-automatic'), this by itself generally affects only startup
time for a program, but when not `SAVE'd, it can slow down the
procedure every time it is called.

   *Note Overly Convenient Command-Line Options: Overly Convenient
Options, for information on the `-fno-automatic' and
`-finit-local-zero' options and how to convert their use into selective
changes in your own code.


File: g77.info,  Node: Avoid f2c Compatibility,  Next: Use Submodel Options,  Prev: Prefer Automatic Uninitialized Variables,  Up: Faster Programs

14.6.3 Avoid f2c Compatibility
------------------------------

If you aren't linking with any code compiled using `f2c', try using the
`-fno-f2c' option when compiling _all_ the code in your program.  (Note
that `libf2c' is _not_ an example of code that is compiled using
`f2c'--it is compiled by a C compiler, typically `gcc'.)


File: g77.info,  Node: Use Submodel Options,  Prev: Avoid f2c Compatibility,  Up: Faster Programs

14.6.4 Use Submodel Options
---------------------------

Using an appropriate `-m' option to generate specific code for your CPU
may be worthwhile, though it may mean the executable won't run on other
versions of the CPU that don't support the same instruction set.  *Note
Hardware Models and Configurations: (gcc)Submodel Options.  For
instance on an x86 system the compiler might have been built--as shown
by `g77 -v'--for the target `i386-pc-linux-gnu', i.e. an `i386' CPU.
In that case to generate code best optimized for a Pentium you could
use the option `-march=pentium'.

   For recent CPUs that don't have explicit support in the released
version of `gcc', it _might_ still be possible to get improvements with
certain `-m' options.

   `-fomit-frame-pointer' can help performance on x86 systems and
others.  It will, however, inhibit debugging on the systems on which it
is not turned on anyway by `-O'.


File: g77.info,  Node: Trouble,  Next: Open Questions,  Prev: Collected Fortran Wisdom,  Up: Top

15 Known Causes of Trouble with GNU Fortran
*******************************************

This section describes known problems that affect users of GNU Fortran.
Most of these are not GNU Fortran bugs per se--if they were, we would
fix them.  But the result for a user might be like the result of a bug.

   Some of these problems are due to bugs in other software, some are
missing features that are too much work to add, and some are places
where people's opinions differ as to what is best.

   (Note that some of this portion of the manual is lifted directly
from the `gcc' manual, with minor modifications to tailor it to users
of `g77'.  Anytime a bug seems to have more to do with the `gcc'
portion of `g77', see *Note Known Causes of Trouble with GCC:
(gcc)Trouble.)

* Menu:

* But-bugs::         Bugs really in other programs or elsewhere.
* Known Bugs::       Bugs known to be in this version of `g77'.
* Missing Features:: Features we already know we want to add later.
* Disappointments::  Regrettable things we can't change.
* Non-bugs::         Things we think are right, but some others disagree.
* Warnings and Errors::  Which problems in your code get warnings,
                        and which get errors.


File: g77.info,  Node: But-bugs,  Next: Known Bugs,  Up: Trouble

15.1 Bugs Not In GNU Fortran
============================

These are bugs to which the maintainers often have to reply, "but that
isn't a bug in `g77'...".  Some of these already are fixed in new
versions of other software; some still need to be fixed; some are
problems with how `g77' is installed or is being used; some are the
result of bad hardware that causes software to misbehave in sometimes
bizarre ways; some just cannot be addressed at this time until more is
known about the problem.

   Please don't re-report these bugs to the `g77' maintainers--if you
must remind someone how important it is to you that the problem be
fixed, talk to the people responsible for the other products identified
below, but preferably only after you've tried the latest versions of
those products.  The `g77' maintainers have their hands full working on
just fixing and improving `g77', without serving as a clearinghouse for
all bugs that happen to affect `g77' users.

   *Note Collected Fortran Wisdom::, for information on behavior of
Fortran programs, and the programs that compile them, that might be
_thought_ to indicate bugs.

* Menu:

* Signal 11 and Friends::  Strange behavior by any software.
* Cannot Link Fortran Programs::  Unresolved references.
* Large Common Blocks::    Problems on older GNU/Linux systems.
* Debugger Problems::      When the debugger crashes.
* NeXTStep Problems::      Misbehaving executables.
* Stack Overflow::         More misbehaving executables.
* Nothing Happens::        Less behaving executables.
* Strange Behavior at Run Time::  Executables misbehaving due to
                            bugs in your program.
* Floating-point Errors::  The results look wrong, but....


File: g77.info,  Node: Signal 11 and Friends,  Next: Cannot Link Fortran Programs,  Up: But-bugs

15.1.1 Signal 11 and Friends
----------------------------

A whole variety of strange behaviors can occur when the software, or
the way you are using the software, stresses the hardware in a way that
triggers hardware bugs.  This might seem hard to believe, but it
happens frequently enough that there exist documents explaining in
detail what the various causes of the problems are, what typical
symptoms look like, and so on.

   Generally these problems are referred to in this document as "signal
11" crashes, because the Linux kernel, running on the most popular
hardware (the Intel x86 line), often stresses the hardware more than
other popular operating systems.  When hardware problems do occur under
GNU/Linux on x86 systems, these often manifest themselves as "signal 11"
problems, as illustrated by the following diagnostic:

     sh# g77 myprog.f
     gcc: Internal compiler error: program f771 got fatal signal 11
     sh#

   It is _very_ important to remember that the above message is _not_
the only one that indicates a hardware problem, nor does it always
indicate a hardware problem.

   In particular, on systems other than those running the Linux kernel,
the message might appear somewhat or very different, as it will if the
error manifests itself while running a program other than the `g77'
compiler.  For example, it will appear somewhat different when running
your program, when running Emacs, and so on.

   How to cope with such problems is well beyond the scope of this
manual.

   However, users of Linux-based systems (such as GNU/Linux) should
review `http://www.bitwizard.nl/sig11/', a source of detailed
information on diagnosing hardware problems, by recognizing their
common symptoms.

   Users of other operating systems and hardware might find this
reference useful as well.  If you know of similar material for another
hardware/software combination, please let us know so we can consider
including a reference to it in future versions of this manual.


File: g77.info,  Node: Cannot Link Fortran Programs,  Next: Large Common Blocks,  Prev: Signal 11 and Friends,  Up: But-bugs

15.1.2 Cannot Link Fortran Programs
-----------------------------------

On some systems, perhaps just those with out-of-date (shared?)
libraries, unresolved-reference errors happen when linking
`g77'-compiled programs (which should be done using `g77').

   If this happens to you, try appending `-lc' to the command you use
to link the program, e.g. `g77 foo.f -lc'.  `g77' already specifies
`-lg2c -lm' when it calls the linker, but it cannot also specify `-lc'
because not all systems have a file named `libc.a'.

   It is unclear at this point whether there are legitimately installed
systems where `-lg2c -lm' is insufficient to resolve code produced by
`g77'.

   If your program doesn't link due to unresolved references to names
like `_main', make sure you're using the `g77' command to do the link,
since this command ensures that the necessary libraries are loaded by
specifying `-lg2c -lm' when it invokes the `gcc' command to do the
actual link.  (Use the `-v' option to discover more about what actually
happens when you use the `g77' and `gcc' commands.)

   Also, try specifying `-lc' as the last item on the `g77' command
line, in case that helps.


File: g77.info,  Node: Large Common Blocks,  Next: Debugger Problems,  Prev: Cannot Link Fortran Programs,  Up: But-bugs

15.1.3 Large Common Blocks
--------------------------

On some older GNU/Linux systems, programs with common blocks larger
than 16MB cannot be linked without some kind of error message being
produced.

   This is a bug in older versions of `ld', fixed in more recent
versions of `binutils', such as version 2.6.


File: g77.info,  Node: Debugger Problems,  Next: NeXTStep Problems,  Prev: Large Common Blocks,  Up: But-bugs

15.1.4 Debugger Problems
------------------------

There are some known problems when using `gdb' on code compiled by
`g77'.  Inadequate investigation as of the release of 0.5.16 results in
not knowing which products are the culprit, but `gdb-4.14' definitely
crashes when, for example, an attempt is made to print the contents of
a `COMPLEX(KIND=2)' dummy array, on at least some GNU/Linux machines,
plus some others.  Attempts to access assumed-size arrays are also
known to crash recent versions of `gdb'.  (`gdb''s Fortran support was
done for a different compiler and isn't properly compatible with `g77'.)


File: g77.info,  Node: NeXTStep Problems,  Next: Stack Overflow,  Prev: Debugger Problems,  Up: But-bugs

15.1.5 NeXTStep Problems
------------------------

Developers of Fortran code on NeXTStep (all architectures) have to
watch out for the following problem when writing programs with large,
statically allocated (i.e. non-stack based) data structures (common
blocks, saved arrays).

   Due to the way the native loader (`/bin/ld') lays out data
structures in virtual memory, it is very easy to create an executable
wherein the `__DATA' segment overlaps (has addresses in common) with
the `UNIX STACK' segment.

   This leads to all sorts of trouble, from the executable simply not
executing, to bus errors.  The NeXTStep command line tool `ebadexec'
points to the problem as follows:

     % /bin/ebadexec a.out
     /bin/ebadexec: __LINKEDIT segment (truncated address = 0x3de000
     rounded size = 0x2a000) of executable file: a.out overlaps with UNIX
     STACK segment (truncated address = 0x400000 rounded size =
     0x3c00000) of executable file: a.out

   (In the above case, it is the `__LINKEDIT' segment that overlaps the
stack segment.)

   This can be cured by assigning the `__DATA' segment (virtual)
addresses beyond the stack segment.  A conservative estimate for this
is from address 6000000 (hexadecimal) onwards--this has always worked
for me [Toon Moene]:

     % g77 -segaddr __DATA 6000000 test.f
     % ebadexec a.out
     ebadexec: file: a.out appears to be executable
     %

   Browsing through `gcc/gcc/f/Makefile.in', you will find that the
`f771' program itself also has to be linked with these flags--it has
large statically allocated data structures.  (Version 0.5.18 reduces
this somewhat, but probably not enough.)

   (The above item was contributed by Toon Moene
(<toon@moene.indiv.nluug.nl>).)


File: g77.info,  Node: Stack Overflow,  Next: Nothing Happens,  Prev: NeXTStep Problems,  Up: But-bugs

15.1.6 Stack Overflow
---------------------

`g77' code might fail at runtime (probably with a "segmentation
violation") due to overflowing the stack.  This happens most often on
systems with an environment that provides substantially more heap space
(for use when arbitrarily allocating and freeing memory) than stack
space.

   Often this can be cured by increasing or removing your shell's limit
on stack usage, typically using `limit stacksize' (in `csh' and
derivatives) or `ulimit -s' (in `sh' and derivatives).

   Increasing the allowed stack size might, however, require changing
some operating system or system configuration parameters.

   You might be able to work around the problem by compiling with the
`-fno-automatic' option to reduce stack usage, probably at the expense
of speed.

   `g77', on most machines, puts many variables and arrays on the stack
where possible, and can be configured (by changing
`FFECOM_sizeMAXSTACKITEM' in `gcc/gcc/f/com.c') to force smaller-sized
entities into static storage (saving on stack space) or permit
larger-sized entities to be put on the stack (which can improve
run-time performance, as it presents more opportunities for the GBE to
optimize the generated code).

   _Note:_ Putting more variables and arrays on the stack might cause
problems due to system-dependent limits on stack size.  Also, the value
of `FFECOM_sizeMAXSTACKITEM' has no effect on automatic variables and
arrays.  *Note But-bugs::, for more information.  _Note:_ While
`libg2c' places a limit on the range of Fortran file-unit numbers, the
underlying library and operating system might impose different kinds of
limits.  For example, some systems limit the number of files
simultaneously open by a running program.  Information on how to
increase these limits should be found in your system's documentation.

   However, if your program uses large automatic arrays (for example,
has declarations like `REAL A(N)' where `A' is a local array and `N' is
a dummy or `COMMON' variable that can have a large value), neither use
of `-fno-automatic', nor changing the cut-off point for `g77' for using
the stack, will solve the problem by changing the placement of these
large arrays, as they are _necessarily_ automatic.

   `g77' currently provides no means to specify that automatic arrays
are to be allocated on the heap instead of the stack.  So, other than
increasing the stack size, your best bet is to change your source code
to avoid large automatic arrays.  Methods for doing this currently are
outside the scope of this document.

   (_Note:_ If your system puts stack and heap space in the same memory
area, such that they are effectively combined, then a stack overflow
probably indicates a program that is either simply too large for the
system, or buggy.)


File: g77.info,  Node: Nothing Happens,  Next: Strange Behavior at Run Time,  Prev: Stack Overflow,  Up: But-bugs

15.1.7 Nothing Happens
----------------------

It is occasionally reported that a "simple" program, such as a "Hello,
World!" program, does nothing when it is run, even though the compiler
reported no errors, despite the program containing nothing other than a
simple `PRINT' statement.

   This most often happens because the program has been compiled and
linked on a UNIX system and named `test', though other names can lead
to similarly unexpected run-time behavior on various systems.

   Essentially this problem boils down to giving your program a name
that is already known to the shell you are using to identify some other
program, which the shell continues to execute instead of your program
when you invoke it via, for example:

     sh# test
     sh#

   Under UNIX and many other system, a simple command name invokes a
searching mechanism that might well not choose the program located in
the current working directory if there is another alternative (such as
the `test' command commonly installed on UNIX systems).

   The reliable way to invoke a program you just linked in the current
directory under UNIX is to specify it using an explicit pathname, as in:

     sh# ./test
      Hello, World!
     sh#

   Users who encounter this problem should take the time to read up on
how their shell searches for commands, how to set their search path,
and so on.  The relevant UNIX commands to learn about include `man',
`info' (on GNU systems), `setenv' (or `set' and `env'), `which', and
`find'.


File: g77.info,  Node: Strange Behavior at Run Time,  Next: Floating-point Errors,  Prev: Nothing Happens,  Up: But-bugs

15.1.8 Strange Behavior at Run Time
-----------------------------------

`g77' code might fail at runtime with "segmentation violation", "bus
error", or even something as subtle as a procedure call overwriting a
variable or array element that it is not supposed to touch.

   These can be symptoms of a wide variety of actual bugs that occurred
earlier during the program's run, but manifested themselves as
_visible_ problems some time later.

   Overflowing the bounds of an array--usually by writing beyond the
end of it--is one of two kinds of bug that often occurs in Fortran code.
(Compile your code with the `-fbounds-check' option to catch many of
these kinds of errors at program run time.)

   The other kind of bug is a mismatch between the actual arguments
passed to a procedure and the dummy arguments as declared by that
procedure.

   Both of these kinds of bugs, and some others as well, can be
difficult to track down, because the bug can change its behavior, or
even appear to not occur, when using a debugger.

   That is, these bugs can be quite sensitive to data, including data
representing the placement of other data in memory (that is, pointers,
such as the placement of stack frames in memory).

   `g77' now offers the ability to catch and report some of these
problems at compile, link, or run time, such as by generating code to
detect references to beyond the bounds of most arrays (except
assumed-size arrays), and checking for agreement between calling and
called procedures.  Future improvements are likely to be made in the
procedure-mismatch area, at least.

   In the meantime, finding and fixing the programming bugs that lead
to these behaviors is, ultimately, the user's responsibility, as
difficult as that task can sometimes be.

   One runtime problem that has been observed might have a simple
solution.  If a formatted `WRITE' produces an endless stream of spaces,
check that your program is linked against the correct version of the C
library.  The configuration process takes care to account for your
system's normal `libc' not being ANSI-standard, which will otherwise
cause this behavior.  If your system's default library is ANSI-standard
and you subsequently link against a non-ANSI one, there might be
problems such as this one.

   Specifically, on Solaris2 systems, avoid picking up the `BSD'
library from `/usr/ucblib'.


File: g77.info,  Node: Floating-point Errors,  Prev: Strange Behavior at Run Time,  Up: But-bugs

15.1.9 Floating-point Errors
----------------------------

Some programs appear to produce inconsistent floating-point results
compiled by `g77' versus by other compilers.

   Often the reason for this behavior is the fact that floating-point
values are represented on almost all Fortran systems by
_approximations_, and these approximations are inexact even for
apparently simple values like 0.1, 0.2, 0.3, 0.4, 0.6, 0.7, 0.8, 0.9,
1.1, and so on.  Most Fortran systems, including all current ports of
`g77', use binary arithmetic to represent these approximations.

   Therefore, the exact value of any floating-point approximation as
manipulated by `g77'-compiled code is representable by adding some
combination of the values 1.0, 0.5, 0.25, 0.125, and so on (just keep
dividing by two) through the precision of the fraction (typically
around 23 bits for `REAL(KIND=1)', 52 for `REAL(KIND=2)'), then
multiplying the sum by a integral power of two (in Fortran, by `2**N')
that typically is between -127 and +128 for `REAL(KIND=1)' and -1023
and +1024 for `REAL(KIND=2)', then multiplying by -1 if the number is
negative.

   So, a value like 0.2 is exactly represented in decimal--since it is
a fraction, `2/10', with a denominator that is compatible with the base
of the number system (base 10).  However, `2/10' cannot be represented
by any finite number of sums of any of 1.0, 0.5, 0.25, and so on, so
0.2 cannot be exactly represented in binary notation.

   (On the other hand, decimal notation can represent any binary number
in a finite number of digits.  Decimal notation cannot do so with
ternary, or base-3, notation, which would represent floating-point
numbers as sums of any of `1/1', `1/3', `1/9', and so on.  After all,
no finite number of decimal digits can exactly represent `1/3'.
Fortunately, few systems use ternary notation.)

   Moreover, differences in the way run-time I/O libraries convert
between these approximations and the decimal representation often used
by programmers and the programs they write can result in apparent
differences between results that do not actually exist, or exist to
such a small degree that they usually are not worth worrying about.

   For example, consider the following program:

     PRINT *, 0.2
     END

   When compiled by `g77', the above program might output `0.20000003',
while another compiler might produce a executable that outputs `0.2'.

   This particular difference is due to the fact that, currently,
conversion of floating-point values by the `libg2c' library, used by
`g77', handles only double-precision values.

   Since `0.2' in the program is a single-precision value, it is
converted to double precision (still in binary notation) before being
converted back to decimal.  The conversion to binary appends _binary_
zero digits to the original value--which, again, is an inexact
approximation of 0.2--resulting in an approximation that is much less
exact than is connoted by the use of double precision.

   (The appending of binary zero digits has essentially the same effect
as taking a particular decimal approximation of `1/3', such as
`0.3333333', and appending decimal zeros to it, producing
`0.33333330000000000'.  Treating the resulting decimal approximation as
if it really had 18 or so digits of valid precision would make it seem
a very poor approximation of `1/3'.)

   As a result of converting the single-precision approximation to
double precision by appending binary zeros, the conversion of the
resulting double-precision value to decimal produces what looks like an
incorrect result, when in fact the result is _inexact_, and is probably
no less inaccurate or imprecise an approximation of 0.2 than is
produced by other compilers that happen to output the converted value
as "exactly" `0.2'.  (Some compilers behave in a way that can make them
appear to retain more accuracy across a conversion of a single-precision
constant to double precision.  *Note Context-Sensitive Constants::, to
see why this practice is illusory and even dangerous.)

   Note that a more exact approximation of the constant is computed
when the program is changed to specify a double-precision constant:

     PRINT *, 0.2D0
     END

   Future versions of `g77' and/or `libg2c' might convert
single-precision values directly to decimal, instead of converting them
to double precision first.  This would tend to result in output that is
more consistent with that produced by some other Fortran
implementations.

   A useful source of information on floating-point computation is David
Goldberg, `What Every Computer Scientist Should Know About
Floating-Point Arithmetic', Computing Surveys, 23, March 1991, pp.
5-48.  An online version is available at `http://docs.sun.com/'.

   Information related to the IEEE 754 floating-point standard by a
leading light can be found at
`http://http.cs.berkeley.edu/%7Ewkahan/ieee754status/'; see also slides
from the short course referenced from
`http://http.cs.berkeley.edu/%7Efateman/'.

   The supplement to the PostScript-formatted Goldberg document,
referenced above, is available in HTML format.  See `Differences Among
IEEE 754 Implementations' by Doug Priest.  This document explores some
of the issues surrounding computing of extended (80-bit) results on
processors such as the x86, especially when those results are
arbitrarily truncated to 32-bit or 64-bit values by the compiler as
"spills".

   (_Note:_ `g77' specifically, and `gcc' generally, does arbitrarily
truncate 80-bit results during spills as of this writing.  It is not
yet clear whether a future version of the GNU compiler suite will offer
80-bit spills as an option, or perhaps even as the default behavior.)

   The GNU C library provides routines for controlling the FPU, and
other documentation about this.

   *Note Floating-point precision::, regarding IEEE 754 conformance.


File: g77.info,  Node: Known Bugs,  Next: Missing Features,  Prev: But-bugs,  Up: Trouble

15.2 Known Bugs In GNU Fortran
==============================

   This section identifies bugs that `g77' _users_ might run into in
the GCC-3.3.6 version of `g77'.  This includes bugs that are actually
in the `gcc' back end (GBE) or in `libf2c', because those sets of code
are at least somewhat under the control of (and necessarily intertwined
with) `g77', so it isn't worth separating them out.

   For information on bugs in _other_ versions of `g77', see *Note News
About GNU Fortran: News.  There, lists of bugs fixed in various
versions of `g77' can help determine what bugs existed in prior
versions.

   An online, "live" version of this document (derived directly from
the mainline, development version of `g77' within `gcc') is available
via `http://gcc.gnu.org/onlinedocs/g77/Trouble.html'.  Follow the
"Known Bugs" link.

   The following information was last updated on 2002-02-01:

   * `g77' fails to warn about use of a "live" iterative-DO variable as
     an implied-DO variable in a `WRITE' or `PRINT' statement (although
     it does warn about this in a `READ' statement).

   * Something about `g77''s straightforward handling of label
     references and definitions sometimes prevents the GBE from
     unrolling loops.  Until this is solved, try inserting or removing
     `CONTINUE' statements as the terminal statement, using the `END DO'
     form instead, and so on.

   * Some confusion in diagnostics concerning failing `INCLUDE'
     statements from within `INCLUDE''d or `#include''d files.

   * `g77' assumes that `INTEGER(KIND=1)' constants range from `-2**31'
     to `2**31-1' (the range for two's-complement 32-bit values),
     instead of determining their range from the actual range of the
     type for the configuration (and, someday, for the constant).

     Further, it generally doesn't implement the handling of constants
     very well in that it makes assumptions about the configuration
     that it no longer makes regarding variables (types).

     Included with this item is the fact that `g77' doesn't recognize
     that, on IEEE-754/854-compliant systems, `0./0.' should produce a
     NaN and no warning instead of the value `0.' and a warning.

   * `g77' uses way too much memory and CPU time to process large
     aggregate areas having any initialized elements.

     For example, `REAL A(1000000)' followed by `DATA A(1)/1/' takes up
     way too much time and space, including the size of the generated
     assembler file.

     Version 0.5.18 improves cases like this--specifically, cases of
     _sparse_ initialization that leave large, contiguous areas
     uninitialized--significantly.  However, even with the
     improvements, these cases still require too much memory and CPU
     time.

     (Version 0.5.18 also improves cases where the initial values are
     zero to a much greater degree, so if the above example ends with
     `DATA A(1)/0/', the compile-time performance will be about as good
     as it will ever get, aside from unrelated improvements to the
     compiler.)

     Note that `g77' does display a warning message to notify the user
     before the compiler appears to hang.  A warning message is issued
     when `g77' sees code that provides initial values (e.g. via
     `DATA') to an aggregate area (`COMMON' or `EQUIVALENCE', or even a
     large enough array or `CHARACTER' variable) that is large enough
     to increase `g77''s compile time by roughly a factor of 10.

     This size currently is quite small, since `g77' currently has a
     known bug requiring too much memory and time to handle such cases.
     In `gcc/gcc/f/data.c', the macro `FFEDATA_sizeTOO_BIG_INIT_' is
     defined to the minimum size for the warning to appear.  The size
     is specified in storage units, which can be bytes, words, or
     whatever, on a case-by-case basis.

     After changing this macro definition, you must (of course) rebuild
     and reinstall `g77' for the change to take effect.

     Note that, as of version 0.5.18, improvements have reduced the
     scope of the problem for _sparse_ initialization of large arrays,
     especially those with large, contiguous uninitialized areas.
     However, the warning is issued at a point prior to when `g77'
     knows whether the initialization is sparse, and delaying the
     warning could mean it is produced too late to be helpful.

     Therefore, the macro definition should not be adjusted to reflect
     sparse cases.  Instead, adjust it to generate the warning when
     densely initialized arrays begin to cause responses noticeably
     slower than linear performance would suggest.

   * When debugging, after starting up the debugger but before being
     able to see the source code for the main program unit, the user
     must currently set a breakpoint at `MAIN__' (or `MAIN___' or
     `MAIN_' if `MAIN__' doesn't exist) and run the program until it
     hits the breakpoint.  At that point, the main program unit is
     activated and about to execute its first executable statement, but
     that's the state in which the debugger should start up, as is the
     case for languages like C.

   * Debugging `g77'-compiled code using debuggers other than `gdb' is
     likely not to work.

     Getting `g77' and `gdb' to work together is a known
     problem--getting `g77' to work properly with other debuggers, for
     which source code often is unavailable to `g77' developers, seems
     like a much larger, unknown problem, and is a lower priority than
     making `g77' and `gdb' work together properly.

     On the other hand, information about problems other debuggers have
     with `g77' output might make it easier to properly fix `g77', and
     perhaps even improve `gdb', so it is definitely welcome.  Such
     information might even lead to all relevant products working
     together properly sooner.

   * `g77' doesn't work perfectly on 64-bit configurations such as the
     Digital Semiconductor ("DEC") Alpha.

     This problem is largely resolved as of version 0.5.23.

   * `g77' currently inserts needless padding for things like `COMMON
     A,IPAD' where `A' is `CHARACTER*1' and `IPAD' is `INTEGER(KIND=1)'
     on machines like x86, because the back end insists that `IPAD' be
     aligned to a 4-byte boundary, but the processor has no such
     requirement (though it is usually good for performance).

     The `gcc' back end needs to provide a wider array of
     specifications of alignment requirements and preferences for
     targets, and front ends like `g77' should take advantage of this
     when it becomes available.

   * The `libf2c' routines that perform some run-time arithmetic on
     `COMPLEX' operands were modified circa version 0.5.20 of `g77' to
     work properly even in the presence of aliased operands.

     While the `g77' and `netlib' versions of `libf2c' differ on how
     this is accomplished, the main differences are that we believe the
     `g77' version works properly even in the presence of _partially_
     aliased operands.

     However, these modifications have reduced performance on targets
     such as x86, due to the extra copies of operands involved.


File: g77.info,  Node: Missing Features,  Next: Disappointments,  Prev: Known Bugs,  Up: Trouble

15.3 Missing Features
=====================

This section lists features we know are missing from `g77', and which
we want to add someday.  (There is no priority implied in the ordering
below.)

* Menu:

GNU Fortran language:
* Better Source Model::
* Fortran 90 Support::
* Intrinsics in PARAMETER Statements::
* Arbitrary Concatenation::
* SELECT CASE on CHARACTER Type::
* RECURSIVE Keyword::
* Popular Non-standard Types::
* Full Support for Compiler Types::
* Array Bounds Expressions::
* POINTER Statements::
* Sensible Non-standard Constructs::
* READONLY Keyword::
* FLUSH Statement::
* Expressions in FORMAT Statements::
* Explicit Assembler Code::
* Q Edit Descriptor::

GNU Fortran dialects:
* Old-style PARAMETER Statements::
* TYPE and ACCEPT I/O Statements::
* STRUCTURE UNION RECORD MAP::
* OPEN CLOSE and INQUIRE Keywords::
* ENCODE and DECODE::
* AUTOMATIC Statement::
* Suppressing Space Padding::
* Fortran Preprocessor::
* Bit Operations on Floating-point Data::
* Really Ugly Character Assignments::

New facilities:
* POSIX Standard::
* Floating-point Exception Handling::
* Nonportable Conversions::
* Large Automatic Arrays::
* Support for Threads::
* Increasing Precision/Range::
* Enabling Debug Lines::

Better diagnostics:
* Better Warnings::
* Gracefully Handle Sensible Bad Code::
* Non-standard Conversions::
* Non-standard Intrinsics::
* Modifying DO Variable::
* Better Pedantic Compilation::
* Warn About Implicit Conversions::
* Invalid Use of Hollerith Constant::
* Dummy Array Without Dimensioning Dummy::
* Invalid FORMAT Specifiers::
* Ambiguous Dialects::
* Unused Labels::
* Informational Messages::

Run-time facilities:
* Uninitialized Variables at Run Time::
* Portable Unformatted Files::
* Better List-directed I/O::
* Default to Console I/O::

Debugging:
* Labels Visible to Debugger::


File: g77.info,  Node: Better Source Model,  Next: Fortran 90 Support,  Up: Missing Features

15.3.1 Better Source Model
--------------------------

`g77' needs to provide, as the default source-line model, a "pure
visual" mode, where the interpretation of a source program in this mode
can be accurately determined by a user looking at a traditionally
displayed rendition of the program (assuming the user knows whether the
program is fixed or free form).

   The design should assume the user cannot tell tabs from spaces and
cannot see trailing spaces on lines, but has canonical tab stops and,
for fixed-form source, has the ability to always know exactly where
column 72 is (since the Fortran standard itself requires this for
fixed-form source).

   This would change the default treatment of fixed-form source to not
treat lines with tabs as if they were infinitely long--instead, they
would end at column 72 just as if the tabs were replaced by spaces in
the canonical way.

   As part of this, provide common alternate models (Digital, `f2c',
and so on) via command-line options.  This includes allowing
arbitrarily long lines for free-form source as well as fixed-form
source and providing various limits and diagnostics as appropriate.

   Also, `g77' should offer, perhaps even default to, warnings when
characters beyond the last valid column are anything other than spaces.
This would mean code with "sequence numbers" in columns 73 through 80
would be rejected, and there's a lot of that kind of code around, but
one of the most frequent bugs encountered by new users is accidentally
writing fixed-form source code into and beyond column 73.  So, maybe
the users of old code would be able to more easily handle having to
specify, say, a `-Wno-col73to80' option.


File: g77.info,  Node: Fortran 90 Support,  Next: Intrinsics in PARAMETER Statements,  Prev: Better Source Model,  Up: Missing Features

15.3.2 Fortran 90 Support
-------------------------

`g77' does not support many of the features that distinguish Fortran 90
(and, now, Fortran 95) from ANSI FORTRAN 77.

   Some Fortran 90 features are supported, because they make sense to
offer even to die-hard users of F77.  For example, many of them codify
various ways F77 has been extended to meet users' needs during its
tenure, so `g77' might as well offer them as the primary way to meet
those same needs, even if it offers compatibility with one or more of
the ways those needs were met by other F77 compilers in the industry.

   Still, many important F90 features are not supported, because no
attempt has been made to research each and every feature and assess its
viability in `g77'.  In the meantime, users who need those features must
use Fortran 90 compilers anyway, and the best approach to adding some
F90 features to GNU Fortran might well be to fund a comprehensive
project to create GNU Fortran 95.


File: g77.info,  Node: Intrinsics in PARAMETER Statements,  Next: Arbitrary Concatenation,  Prev: Fortran 90 Support,  Up: Missing Features

15.3.3 Intrinsics in `PARAMETER' Statements
-------------------------------------------

`g77' doesn't allow intrinsics in `PARAMETER' statements.

   Related to this, `g77' doesn't allow non-integral exponentiation in
`PARAMETER' statements, such as `PARAMETER (R=2**.25)'.  It is unlikely
`g77' will ever support this feature, as doing it properly requires
complete emulation of a target computer's floating-point facilities when
building `g77' as a cross-compiler.  But, if the `gcc' back end is
enhanced to provide such a facility, `g77' will likely use that facility
in implementing this feature soon afterwards.


File: g77.info,  Node: Arbitrary Concatenation,  Next: SELECT CASE on CHARACTER Type,  Prev: Intrinsics in PARAMETER Statements,  Up: Missing Features

15.3.4 Arbitrary Concatenation
------------------------------

`g77' doesn't support arbitrary operands for concatenation in contexts
where run-time allocation is required.  For example:

     SUBROUTINE X(A)
     CHARACTER*(*) A
     CALL FOO(A // 'suffix')


File: g77.info,  Node: SELECT CASE on CHARACTER Type,  Next: RECURSIVE Keyword,  Prev: Arbitrary Concatenation,  Up: Missing Features

15.3.5 `SELECT CASE' on `CHARACTER' Type
----------------------------------------

Character-type selector/cases for `SELECT CASE' currently are not
supported.


File: g77.info,  Node: RECURSIVE Keyword,  Next: Popular Non-standard Types,  Prev: SELECT CASE on CHARACTER Type,  Up: Missing Features

15.3.6 `RECURSIVE' Keyword
--------------------------

`g77' doesn't support the `RECURSIVE' keyword that F90 compilers do.
Nor does it provide any means for compiling procedures designed to do
recursion.

   All recursive code can be rewritten to not use recursion, but the
result is not pretty.


File: g77.info,  Node: Increasing Precision/Range,  Next: Enabling Debug Lines,  Prev: Support for Threads,  Up: Missing Features

15.3.7 Increasing Precision/Range
---------------------------------

Some compilers, such as `f2c', have an option (`-r8', `-qrealsize=8' or
similar) that provides automatic treatment of `REAL' entities such that
they have twice the storage size, and a corresponding increase in the
range and precision, of what would normally be the `REAL(KIND=1)'
(default `REAL') type.  (This affects `COMPLEX' the same way.)

   They also typically offer another option (`-i8') to increase
`INTEGER' entities so they are twice as large (with roughly twice as
much range).

   (There are potential pitfalls in using these options.)

   `g77' does not yet offer any option that performs these kinds of
transformations.  Part of the problem is the lack of detailed
specifications regarding exactly how these options affect the
interpretation of constants, intrinsics, and so on.

   Until `g77' addresses this need, programmers could improve the
portability of their code by modifying it to not require compile-time
options to produce correct results.  Some free tools are available
which may help, specifically in Toolpack (which one would expect to be
sound) and the `fortran' section of the Netlib repository.

   Use of preprocessors can provide a fairly portable means to work
around the lack of widely portable methods in the Fortran language
itself (though increasing acceptance of Fortran 90 would alleviate this
problem).


File: g77.info,  Node: Popular Non-standard Types,  Next: Full Support for Compiler Types,  Prev: RECURSIVE Keyword,  Up: Missing Features

15.3.8 Popular Non-standard Types
---------------------------------

`g77' doesn't fully support `INTEGER*2', `LOGICAL*1', and similar.  In
the meantime, version 0.5.18 provides rudimentary support for them.


File: g77.info,  Node: Full Support for Compiler Types,  Next: Array Bounds Expressions,  Prev: Popular Non-standard Types,  Up: Missing Features

15.3.9 Full Support for Compiler Types
--------------------------------------

`g77' doesn't support `INTEGER', `REAL', and `COMPLEX' equivalents for
_all_ applicable back-end-supported types (`char', `short int', `int',
`long int', `long long int', and `long double').  This means providing
intrinsic support, and maybe constant support (using F90 syntax) as
well, and, for most machines will result in automatic support of
`INTEGER*1', `INTEGER*2', `INTEGER*8', maybe even `REAL*16', and so on.


File: g77.info,  Node: Array Bounds Expressions,  Next: POINTER Statements,  Prev: Full Support for Compiler Types,  Up: Missing Features

15.3.10 Array Bounds Expressions
--------------------------------

`g77' doesn't support more general expressions to dimension arrays,
such as array element references, function references, etc.

   For example, `g77' currently does not accept the following:

     SUBROUTINE X(M, N)
     INTEGER N(10), M(N(2), N(1))


File: g77.info,  Node: POINTER Statements,  Next: Sensible Non-standard Constructs,  Prev: Array Bounds Expressions,  Up: Missing Features

15.3.11 POINTER Statements
--------------------------

`g77' doesn't support pointers or allocatable objects (other than
automatic arrays).  This set of features is probably considered just
behind intrinsics in `PARAMETER' statements on the list of large,
important things to add to `g77'.

   In the meantime, consider using the `INTEGER(KIND=7)' declaration to
specify that a variable must be able to hold a pointer.  This construct
is not portable to other non-GNU compilers, but it is portable to all
machines GNU Fortran supports when `g77' is used.

   *Note Functions and Subroutines::, for information on `%VAL()',
`%REF()', and `%DESCR()' constructs, which are useful for passing
pointers to procedures written in languages other than Fortran.


File: g77.info,  Node: Sensible Non-standard Constructs,  Next: READONLY Keyword,  Prev: POINTER Statements,  Up: Missing Features

15.3.12 Sensible Non-standard Constructs
----------------------------------------

`g77' rejects things other compilers accept, like `INTRINSIC SQRT,SQRT'.
As time permits in the future, some of these things that are easy for
humans to read and write and unlikely to be intended to mean something
else will be accepted by `g77' (though `-fpedantic' should trigger
warnings about such non-standard constructs).

   Until `g77' no longer gratuitously rejects sensible code, you might
as well fix your code to be more standard-conforming and portable.

   The kind of case that is important to except from the recommendation
to change your code is one where following good coding rules would
force you to write non-standard code that nevertheless has a clear
meaning.

   For example, when writing an `INCLUDE' file that defines a common
block, it might be appropriate to include a `SAVE' statement for the
common block (such as `SAVE /CBLOCK/'), so that variables defined in
the common block retain their values even when all procedures declaring
the common block become inactive (return to their callers).

   However, putting `SAVE' statements in an `INCLUDE' file would
prevent otherwise standard-conforming code from also specifying the
`SAVE' statement, by itself, to indicate that all local variables and
arrays are to have the `SAVE' attribute.

   For this reason, `g77' already has been changed to allow this
combination, because although the general problem of gratuitously
rejecting unambiguous and "safe" constructs still exists in `g77', this
particular construct was deemed useful enough that it was worth fixing
`g77' for just this case.

   So, while there is no need to change your code to avoid using this
particular construct, there might be other, equally appropriate but
non-standard constructs, that you shouldn't have to stop using just
because `g77' (or any other compiler) gratuitously rejects it.

   Until the general problem is solved, if you have any such construct
you believe is worthwhile using (e.g. not just an arbitrary, redundant
specification of an attribute), please submit a bug report with an
explanation, so we can consider fixing `g77' just for cases like yours.


File: g77.info,  Node: READONLY Keyword,  Next: FLUSH Statement,  Prev: Sensible Non-standard Constructs,  Up: Missing Features

15.3.13 `READONLY' Keyword
--------------------------

Support for `READONLY', in `OPEN' statements, requires `libg2c' support,
to make sure that `CLOSE(...,STATUS='DELETE')' does not delete a file
opened on a unit with the `READONLY' keyword, and perhaps to trigger a
fatal diagnostic if a `WRITE' or `PRINT' to such a unit is attempted.

   _Note:_ It is not sufficient for `g77' and `libg2c' (its version of
`libf2c') to assume that `READONLY' does not need some kind of explicit
support at run time, due to UNIX systems not (generally) needing it.
`g77' is not just a UNIX-based compiler!

   Further, mounting of non-UNIX filesystems on UNIX systems (such as
via NFS) might require proper `READONLY' support.

   (Similar issues might be involved with supporting the `SHARED'
keyword.)


File: g77.info,  Node: FLUSH Statement,  Next: Expressions in FORMAT Statements,  Prev: READONLY Keyword,  Up: Missing Features

15.3.14 `FLUSH' Statement
-------------------------

`g77' could perhaps use a `FLUSH' statement that does what `CALL FLUSH'
does, but that supports `*' as the unit designator (same unit as for
`PRINT') and accepts `ERR=' and/or `IOSTAT=' specifiers.


File: g77.info,  Node: Expressions in FORMAT Statements,  Next: Explicit Assembler Code,  Prev: FLUSH Statement,  Up: Missing Features

15.3.15 Expressions in `FORMAT' Statements
------------------------------------------

`g77' doesn't support `FORMAT(I<J>)' and the like.  Supporting this
requires a significant redesign or replacement of `libg2c'.

   However, `g77' does support this construct when the expression is
constant (as of version 0.5.22).  For example:

           PARAMETER (IWIDTH = 12)
     10    FORMAT (I<IWIDTH>)

   Otherwise, at least for output (`PRINT' and `WRITE'), Fortran code
making use of this feature can be rewritten to avoid it by constructing
the `FORMAT' string in a `CHARACTER' variable or array, then using that
variable or array in place of the `FORMAT' statement label to do the
original `PRINT' or `WRITE'.

   Many uses of this feature on input can be rewritten this way as
well, but not all can.  For example, this can be rewritten:

           READ 20, I
     20    FORMAT (I<J>)

   However, this cannot, in general, be rewritten, especially when
`ERR=' and `END=' constructs are employed:

           READ 30, J, I
     30    FORMAT (I<J>)


File: g77.info,  Node: Explicit Assembler Code,  Next: Q Edit Descriptor,  Prev: Expressions in FORMAT Statements,  Up: Missing Features

15.3.16 Explicit Assembler Code
-------------------------------

`g77' needs to provide some way, a la `gcc', for `g77' code to specify
explicit assembler code.


File: g77.info,  Node: Q Edit Descriptor,  Next: Old-style PARAMETER Statements,  Prev: Explicit Assembler Code,  Up: Missing Features

15.3.17 Q Edit Descriptor
-------------------------

The `Q' edit descriptor in `FORMAT's isn't supported.  (This is meant
to get the number of characters remaining in an input record.)
Supporting this requires a significant redesign or replacement of
`libg2c'.

   A workaround might be using internal I/O or the stream-based
intrinsics.  *Note FGetC Intrinsic (subroutine)::.


File: g77.info,  Node: Old-style PARAMETER Statements,  Next: TYPE and ACCEPT I/O Statements,  Prev: Q Edit Descriptor,  Up: Missing Features

15.3.18 Old-style PARAMETER Statements
--------------------------------------

`g77' doesn't accept `PARAMETER I=1'.  Supporting this obsolete form of
the `PARAMETER' statement would not be particularly hard, as most of the
parsing code is already in place and working.

   Until time/money is spent implementing it, you might as well fix
your code to use the standard form, `PARAMETER (I=1)' (possibly needing
`INTEGER I' preceding the `PARAMETER' statement as well, otherwise, in
the obsolete form of `PARAMETER', the type of the variable is set from
the type of the constant being assigned to it).


File: g77.info,  Node: TYPE and ACCEPT I/O Statements,  Next: STRUCTURE UNION RECORD MAP,  Prev: Old-style PARAMETER Statements,  Up: Missing Features

15.3.19 `TYPE' and `ACCEPT' I/O Statements
------------------------------------------

`g77' doesn't support the I/O statements `TYPE' and `ACCEPT'.  These
are common extensions that should be easy to support, but also are
fairly easy to work around in user code.

   Generally, any `TYPE fmt,list' I/O statement can be replaced by
`PRINT fmt,list'.  And, any `ACCEPT fmt,list' statement can be replaced
by `READ fmt,list'.


File: g77.info,  Node: STRUCTURE UNION RECORD MAP,  Next: OPEN CLOSE and INQUIRE Keywords,  Prev: TYPE and ACCEPT I/O Statements,  Up: Missing Features

15.3.20 `STRUCTURE', `UNION', `RECORD', `MAP'
---------------------------------------------

`g77' doesn't support `STRUCTURE', `UNION', `RECORD', `MAP'.  This set
of extensions is quite a bit lower on the list of large, important
things to add to `g77', partly because it requires a great deal of work
either upgrading or replacing `libg2c'.


File: g77.info,  Node: OPEN CLOSE and INQUIRE Keywords,  Next: ENCODE and DECODE,  Prev: STRUCTURE UNION RECORD MAP,  Up: Missing Features

15.3.21 `OPEN', `CLOSE', and `INQUIRE' Keywords
-----------------------------------------------

`g77' doesn't have support for keywords such as `DISP='DELETE'' in the
`OPEN', `CLOSE', and `INQUIRE' statements.  These extensions are easy
to add to `g77' itself, but require much more work on `libg2c'.

   `g77' doesn't support `FORM='PRINT'' or an equivalent to translate
the traditional `carriage control' characters in column 1 of output to
use backspaces, carriage returns and the like.  However programs exist
to translate them in output files (or standard output).  These are
typically called either `fpr' or `asa'.  You can get a version of `asa'
from `ftp://sunsite.unc.edu/pub/Linux/devel/lang/fortran' for GNU
systems which will probably build easily on other systems.
Alternatively, `fpr' is in BSD distributions in various archive sites.


File: g77.info,  Node: ENCODE and DECODE,  Next: AUTOMATIC Statement,  Prev: OPEN CLOSE and INQUIRE Keywords,  Up: Missing Features

15.3.22 `ENCODE' and `DECODE'
-----------------------------

`g77' doesn't support `ENCODE' or `DECODE'.

   These statements are best replaced by READ and WRITE statements
involving internal files (CHARACTER variables and arrays).

   For example, replace a code fragment like

           INTEGER*1 LINE(80)
     ...
           DECODE (80, 9000, LINE) A, B, C
     ...
     9000  FORMAT (1X, 3(F10.5))

with:

           CHARACTER*80 LINE
     ...
           READ (UNIT=LINE, FMT=9000) A, B, C
     ...
     9000  FORMAT (1X, 3(F10.5))

   Similarly, replace a code fragment like

           INTEGER*1 LINE(80)
     ...
           ENCODE (80, 9000, LINE) A, B, C
     ...
     9000  FORMAT (1X, 'OUTPUT IS ', 3(F10.5))

with:

           CHARACTER*80 LINE
     ...
           WRITE (UNIT=LINE, FMT=9000) A, B, C
     ...
     9000  FORMAT (1X, 'OUTPUT IS ', 3(F10.5))

   It is entirely possible that `ENCODE' and `DECODE' will be supported
by a future version of `g77'.


File: g77.info,  Node: AUTOMATIC Statement,  Next: Suppressing Space Padding,  Prev: ENCODE and DECODE,  Up: Missing Features

15.3.23 `AUTOMATIC' Statement
-----------------------------

`g77' doesn't support the `AUTOMATIC' statement that `f2c' does.

   `AUTOMATIC' would identify a variable or array as not being
`SAVE''d, which is normally the default, but which would be especially
useful for code that, _generally_, needed to be compiled with the
`-fno-automatic' option.

   `AUTOMATIC' also would serve as a hint to the compiler that placing
the variable or array--even a very large array-on the stack is
acceptable.

   `AUTOMATIC' would not, by itself, designate the containing procedure
as recursive.

   `AUTOMATIC' should work syntactically like `SAVE', in that
`AUTOMATIC' with no variables listed should apply to all pertinent
variables and arrays (which would not include common blocks or their
members).

   Variables and arrays denoted as `AUTOMATIC' would not be permitted
to be initialized via `DATA' or other specification of any initial
values, requiring explicit initialization, such as via assignment
statements.

   Perhaps `UNSAVE' and `STATIC', as strict semantic opposites to
`SAVE' and `AUTOMATIC', should be provided as well.


File: g77.info,  Node: Suppressing Space Padding,  Next: Fortran Preprocessor,  Prev: AUTOMATIC Statement,  Up: Missing Features

15.3.24 Suppressing Space Padding of Source Lines
-------------------------------------------------

`g77' should offer VXT-Fortran-style suppression of virtual spaces at
the end of a source line if an appropriate command-line option is
specified.

   This affects cases where a character constant is continued onto the
next line in a fixed-form source file, as in the following example:

     10    PRINT *,'HOW MANY
          1 SPACES?'

`g77', and many other compilers, virtually extend the continued line
through column 72 with spaces that become part of the character
constant, but Digital Fortran normally didn't, leaving only one space
between `MANY' and `SPACES?' in the output of the above statement.

   Fairly recently, at least one version of Digital Fortran was
enhanced to provide the other behavior when a command-line option is
specified, apparently due to demand from readers of the USENET group
`comp.lang.fortran' to offer conformance to this widespread practice in
the industry.  `g77' should return the favor by offering conformance to
Digital's approach to handling the above example.


File: g77.info,  Node: Fortran Preprocessor,  Next: Bit Operations on Floating-point Data,  Prev: Suppressing Space Padding,  Up: Missing Features

15.3.25 Fortran Preprocessor
----------------------------

`g77' should offer a preprocessor designed specifically for Fortran to
replace `cpp -traditional'.  There are several out there worth
evaluating, at least.

   Such a preprocessor would recognize Hollerith constants, properly
parse comments and character constants, and so on.  It might also
recognize, process, and thus preprocess files included via the
`INCLUDE' directive.


File: g77.info,  Node: Bit Operations on Floating-point Data,  Next: Really Ugly Character Assignments,  Prev: Fortran Preprocessor,  Up: Missing Features

15.3.26 Bit Operations on Floating-point Data
---------------------------------------------

`g77' does not allow `REAL' and other non-integral types for arguments
to intrinsics like `And', `Or', and `Shift'.

   For example, this program is rejected by `g77', because the
intrinsic `Iand' does not accept `REAL' arguments:

     DATA A/7.54/, B/9.112/
     PRINT *, IAND(A, B)
     END


File: g77.info,  Node: Really Ugly Character Assignments,  Next: POSIX Standard,  Prev: Bit Operations on Floating-point Data,  Up: Missing Features

15.3.27 Really Ugly Character Assignments
-----------------------------------------

An option such as `-fugly-char' should be provided to allow

     REAL*8 A1
     DATA A1 / '12345678' /

   and:

     REAL*8 A1
     A1 = 'ABCDEFGH'


File: g77.info,  Node: POSIX Standard,  Next: Floating-point Exception Handling,  Prev: Really Ugly Character Assignments,  Up: Missing Features

15.3.28 `POSIX' Standard
------------------------

`g77' should support the POSIX standard for Fortran.


File: g77.info,  Node: Floating-point Exception Handling,  Next: Nonportable Conversions,  Prev: POSIX Standard,  Up: Missing Features

15.3.29 Floating-point Exception Handling
-----------------------------------------

The `gcc' backend and, consequently, `g77', currently provides no
general control over whether or not floating-point exceptions are
trapped or ignored.  (Ignoring them typically results in NaN values
being propagated in systems that conform to IEEE 754.)  The behavior is
normally inherited from the system-dependent startup code, though some
targets, such as the Alpha, have code generation options which change
the behavior.

   Most systems provide some C-callable mechanism to change this; this
can be invoked at startup using `gcc''s `constructor' attribute.  For
example, just compiling and linking the following C code with your
program will turn on exception trapping for the "common" exceptions on
a GNU system using glibc 2.2 or newer:

     #define _GNU_SOURCE 1
     #include <fenv.h>
     static void __attribute__ ((constructor))
     trapfpe ()
     {
       /* Enable some exceptions.  At startup all exceptions are masked.  */

       feenableexcept (FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW);
     }

   A convenient trick is to compile this something like:
     gcc -o libtrapfpe.a trapfpe.c
   and then use it by adding `-trapfpe' to the `g77' command line when
linking.


File: g77.info,  Node: Nonportable Conversions,  Next: Large Automatic Arrays,  Prev: Floating-point Exception Handling,  Up: Missing Features

15.3.30 Nonportable Conversions
-------------------------------

`g77' doesn't accept some particularly nonportable, silent data-type
conversions such as `LOGICAL' to `REAL' (as in `A=.FALSE.', where `A'
is type `REAL'), that other compilers might quietly accept.

   Some of these conversions are accepted by `g77' when the
`-fugly-logint' option is specified.  Perhaps it should accept more or
all of them.


File: g77.info,  Node: Large Automatic Arrays,  Next: Support for Threads,  Prev: Nonportable Conversions,  Up: Missing Features

15.3.31 Large Automatic Arrays
------------------------------

Currently, automatic arrays always are allocated on the stack.  For
situations where the stack cannot be made large enough, `g77' should
offer a compiler option that specifies allocation of automatic arrays
in heap storage.


File: g77.info,  Node: Support for Threads,  Next: Increasing Precision/Range,  Prev: Large Automatic Arrays,  Up: Missing Features

15.3.32 Support for Threads
---------------------------

Neither the code produced by `g77' nor the `libg2c' library are
thread-safe, nor does `g77' have support for parallel processing (other
than the instruction-level parallelism available on some processors).
A package such as PVM might help here.


File: g77.info,  Node: Enabling Debug Lines,  Next: Better Warnings,  Prev: Increasing Precision/Range,  Up: Missing Features

15.3.33 Enabling Debug Lines
----------------------------

An option such as `-fdebug-lines' should be provided to turn fixed-form
lines beginning with `D' to be treated as if they began with a space,
instead of as if they began with a `C' (as comment lines).


File: g77.info,  Node: Better Warnings,  Next: Gracefully Handle Sensible Bad Code,  Prev: Enabling Debug Lines,  Up: Missing Features

15.3.34 Better Warnings
-----------------------

Because of how `g77' generates code via the back end, it doesn't always
provide warnings the user wants.  Consider:

     PROGRAM X
     PRINT *, A
     END

   Currently, the above is not flagged as a case of using an
uninitialized variable, because `g77' generates a run-time library call
that looks, to the GBE, like it might actually _modify_ `A' at run time.
(And, in fact, depending on the previous run-time library call, it
would!)

   Fixing this requires one of the following:

   * Switch to new library, `libg77', that provides a more "clean"
     interface, vis-a-vis input, output, and modified arguments, so the
     GBE can tell what's going on.

     This would provide a pretty big performance improvement, at least
     theoretically, and, ultimately, in practice, for some types of
     code.

   * Have `g77' pass a pointer to a temporary containing a copy of `A',
     instead of to `A' itself.  The GBE would then complain about the
     copy operation involving a potentially uninitialized variable.

     This might also provide a performance boost for some code, because
     `A' might then end up living in a register, which could help with
     inner loops.

   * Have `g77' use a GBE construct similar to `ADDR_EXPR' but with
     extra information on the fact that the item pointed to won't be
     modified (a la `const' in C).

     Probably the best solution for now, but not quite trivial to
     implement in the general case.


File: g77.info,  Node: Gracefully Handle Sensible Bad Code,  Next: Non-standard Conversions,  Prev: Better Warnings,  Up: Missing Features

15.3.35 Gracefully Handle Sensible Bad Code
-------------------------------------------

`g77' generally should continue processing for warnings and recoverable
(user) errors whenever possible--that is, it shouldn't gratuitously
make bad or useless code.

   For example:

     INTRINSIC ZABS
     CALL FOO(ZABS)
     END

When compiling the above with `-ff2c-intrinsics-disable', `g77' should
indeed complain about passing `ZABS', but it still should compile,
instead of rejecting the entire `CALL' statement.  (Some of this is
related to improving the compiler internals to improve how statements
are analyzed.)


File: g77.info,  Node: Non-standard Conversions,  Next: Non-standard Intrinsics,  Prev: Gracefully Handle Sensible Bad Code,  Up: Missing Features

15.3.36 Non-standard Conversions
--------------------------------

`-Wconversion' and related should flag places where non-standard
conversions are found.  Perhaps much of this would be part of `-Wugly*'.


File: g77.info,  Node: Non-standard Intrinsics,  Next: Modifying DO Variable,  Prev: Non-standard Conversions,  Up: Missing Features

15.3.37 Non-standard Intrinsics
-------------------------------

`g77' needs a new option, like `-Wintrinsics', to warn about use of
non-standard intrinsics without explicit `INTRINSIC' statements for
them.  This would help find code that might fail silently when ported
to another compiler.


File: g77.info,  Node: Modifying DO Variable,  Next: Better Pedantic Compilation,  Prev: Non-standard Intrinsics,  Up: Missing Features

15.3.38 Modifying `DO' Variable
-------------------------------

`g77' should warn about modifying `DO' variables via `EQUIVALENCE'.
(The internal information gathered to produce this warning might also
be useful in setting the internal "doiter" flag for a variable or even
array reference within a loop, since that might produce faster code
someday.)

   For example, this code is invalid, so `g77' should warn about the
invalid assignment to `NOTHER':

     EQUIVALENCE (I, NOTHER)
     DO I = 1, 100
        IF (I.EQ. 10) NOTHER = 20
     END DO


File: g77.info,  Node: Better Pedantic Compilation,  Next: Warn About Implicit Conversions,  Prev: Modifying DO Variable,  Up: Missing Features

15.3.39 Better Pedantic Compilation
-----------------------------------

`g77' needs to support `-fpedantic' more thoroughly, and use it only to
generate warnings instead of rejecting constructs outright.  Have it
warn: if a variable that dimensions an array is not a dummy or placed
explicitly in `COMMON' (F77 does not allow it to be placed in `COMMON'
via `EQUIVALENCE'); if specification statements follow
statement-function-definition statements; about all sorts of syntactic
extensions.


File: g77.info,  Node: Warn About Implicit Conversions,  Next: Invalid Use of Hollerith Constant,  Prev: Better Pedantic Compilation,  Up: Missing Features

15.3.40 Warn About Implicit Conversions
---------------------------------------

`g77' needs a `-Wpromotions' option to warn if source code appears to
expect automatic, silent, and somewhat dangerous compiler-assisted
conversion of `REAL(KIND=1)' constants to `REAL(KIND=2)' based on
context.

   For example, it would warn about cases like this:

     DOUBLE PRECISION FOO
     PARAMETER (TZPHI = 9.435784839284958)
     FOO = TZPHI * 3D0


File: g77.info,  Node: Invalid Use of Hollerith Constant,  Next: Dummy Array Without Dimensioning Dummy,  Prev: Warn About Implicit Conversions,  Up: Missing Features

15.3.41 Invalid Use of Hollerith Constant
-----------------------------------------

`g77' should disallow statements like `RETURN 2HAB', which are invalid
in both source forms (unlike `RETURN (2HAB)', which probably still
makes no sense but at least can be reliably parsed).  Fixed-form
processing rejects it, but not free-form, except in a way that is a bit
difficult to understand.


File: g77.info,  Node: Dummy Array Without Dimensioning Dummy,  Next: Invalid FORMAT Specifiers,  Prev: Invalid Use of Hollerith Constant,  Up: Missing Features

15.3.42 Dummy Array Without Dimensioning Dummy
----------------------------------------------

`g77' should complain when a list of dummy arguments containing an
adjustable dummy array does not also contain every variable listed in
the dimension list of the adjustable array.

   Currently, `g77' does complain about a variable that dimensions an
array but doesn't appear in any dummy list or `COMMON' area, but this
needs to be extended to catch cases where it doesn't appear in every
dummy list that also lists any arrays it dimensions.

   For example, `g77' should warn about the entry point `ALT' below,
since it includes `ARRAY' but not `ISIZE' in its list of arguments:

     SUBROUTINE PRIMARY(ARRAY, ISIZE)
     REAL ARRAY(ISIZE)
     ENTRY ALT(ARRAY)


File: g77.info,  Node: Invalid FORMAT Specifiers,  Next: Ambiguous Dialects,  Prev: Dummy Array Without Dimensioning Dummy,  Up: Missing Features

15.3.43 Invalid FORMAT Specifiers
---------------------------------

`g77' should check `FORMAT' specifiers for validity as it does `FORMAT'
statements.

   For example, a diagnostic would be produced for:

     PRINT 'HI THERE!'  !User meant PRINT *, 'HI THERE!'


File: g77.info,  Node: Ambiguous Dialects,  Next: Unused Labels,  Prev: Invalid FORMAT Specifiers,  Up: Missing Features

15.3.44 Ambiguous Dialects
--------------------------

`g77' needs a set of options such as `-Wugly*', `-Wautomatic', `-Wvxt',
`-Wf90', and so on.  These would warn about places in the user's source
where ambiguities are found, helpful in resolving ambiguities in the
program's dialect or dialects.


File: g77.info,  Node: Unused Labels,  Next: Informational Messages,  Prev: Ambiguous Dialects,  Up: Missing Features

15.3.45 Unused Labels
---------------------

`g77' should warn about unused labels when `-Wunused' is in effect.


File: g77.info,  Node: Informational Messages,  Next: Uninitialized Variables at Run Time,  Prev: Unused Labels,  Up: Missing Features

15.3.46 Informational Messages
------------------------------

`g77' needs an option to suppress information messages (notes).  `-w'
does this but also suppresses warnings.  The default should be to
suppress info messages.

   Perhaps info messages should simply be eliminated.


File: g77.info,  Node: Uninitialized Variables at Run Time,  Next: Portable Unformatted Files,  Prev: Informational Messages,  Up: Missing Features

15.3.47 Uninitialized Variables at Run Time
-------------------------------------------

`g77' needs an option to initialize everything (not otherwise
explicitly initialized) to "weird" (machine-dependent) values, e.g.
NaNs, bad (non-`NULL') pointers, and largest-magnitude integers, would
help track down references to some kinds of uninitialized variables at
run time.

   Note that use of the options `-O -Wuninitialized' can catch many
such bugs at compile time.


File: g77.info,  Node: Portable Unformatted Files,  Next: Better List-directed I/O,  Prev: Uninitialized Variables at Run Time,  Up: Missing Features

15.3.48 Portable Unformatted Files
----------------------------------

`g77' has no facility for exchanging unformatted files with systems
using different number formats--even differing only in endianness (byte
order)--or written by other compilers.  Some compilers provide
facilities at least for doing byte-swapping during unformatted I/O.

   It is unrealistic to expect to cope with exchanging unformatted files
with arbitrary other compiler runtimes, but the `g77' runtime should at
least be able to read files written by `g77' on systems with different
number formats, particularly if they differ only in byte order.

   In case you do need to write a program to translate to or from `g77'
(`libf2c') unformatted files, they are written as follows:
Sequential
     Unformatted sequential records consist of
       1. A number giving the length of the record contents;

       2. the length of record contents again (for backspace).

     The record length is of C type `long'; this means that it is 8
     bytes on 64-bit systems such as Alpha GNU/Linux and 4 bytes on
     other systems, such as x86 GNU/Linux.  Consequently such files
     cannot be exchanged between 64-bit and 32-bit systems, even with
     the same basic number format.

Direct access
     Unformatted direct access files form a byte stream of length
     RECORDS*RECL bytes, where RECORDS is the maximum record number
     (`REC=RECORDS') written and RECL is the record length in bytes
     specified in the `OPEN' statement (`RECL=RECL').  Data appear in
     the records as determined by the relevant `WRITE' statement.
     Dummy records with arbitrary contents appear in the file in place
     of records which haven't been written.

   Thus for exchanging a sequential or direct access unformatted file
between big- and little-endian 32-bit systems using IEEE 754 floating
point it would be sufficient to reverse the bytes in consecutive words
in the file if, and _only_ if, only `REAL*4', `COMPLEX', `INTEGER*4'
and/or `LOGICAL*4' data have been written to it by `g77'.

   If necessary, it is possible to do byte-oriented i/o with `g77''s
`FGETC' and `FPUTC' intrinsics.  Byte-swapping can be done in Fortran
by equivalencing larger sized variables to an `INTEGER*1' array or a
set of scalars.

   If you need to exchange binary data between arbitrary system and
compiler variations, we recommend using a portable binary format with
Fortran bindings, such as NCSA's HDF (`http://hdf.ncsa.uiuc.edu/') or
PACT's PDB(1) (`http://www.llnl.gov/def_sci/pact/pact_homepage.html').
(Unlike, say, CDF or XDR, HDF-like systems write in the native number
formats and only incur overhead when they are read on a system with a
different format.)  A future `g77' runtime library should use such
techniques.

   ---------- Footnotes ----------

   (1) No, not _that_ one.


File: g77.info,  Node: Better List-directed I/O,  Next: Default to Console I/O,  Prev: Portable Unformatted Files,  Up: Missing Features

15.3.49 Better List-directed I/O
--------------------------------

Values output using list-directed I/O (`PRINT *, R, D') should be
written with a field width, precision, and so on appropriate for the
type (precision) of each value.

   (Currently, no distinction is made between single-precision and
double-precision values by `libf2c'.)

   It is likely this item will require the `libg77' project to be
undertaken.

   In the meantime, use of formatted I/O is recommended.  While it
might be of little consolation, `g77' does support
`FORMAT(F<WIDTH>.4)', for example, as long as `WIDTH' is defined as a
named constant (via `PARAMETER').  That at least allows some
compile-time specification of the precision of a data type, perhaps
controlled by preprocessing directives.


File: g77.info,  Node: Default to Console I/O,  Next: Labels Visible to Debugger,  Prev: Better List-directed I/O,  Up: Missing Features

15.3.50 Default to Console I/O
------------------------------

The default I/O units, specified by `READ FMT', `READ (UNIT=*)', `WRITE
(UNIT=*)', and `PRINT FMT', should not be units 5 (input) and 6
(output), but, rather, unit numbers not normally available for use in
statements such as `OPEN' and `CLOSE'.

   Changing this would allow a program to connect units 5 and 6 to
files via `OPEN', but still use `READ (UNIT=*)' and `PRINT' to do I/O
to the "console".

   This change probably requires the `libg77' project.


File: g77.info,  Node: Labels Visible to Debugger,  Prev: Default to Console I/O,  Up: Missing Features

15.3.51 Labels Visible to Debugger
----------------------------------

`g77' should output debugging information for statements labels, for
use by debuggers that know how to support them.  Same with weirder
things like construct names.  It is not yet known if any debug formats
or debuggers support these.


File: g77.info,  Node: Disappointments,  Next: Non-bugs,  Prev: Missing Features,  Up: Trouble

15.4 Disappointments and Misunderstandings
==========================================

These problems are perhaps regrettable, but we don't know any practical
way around them for now.

* Menu:

* Mangling of Names::                       `SUBROUTINE FOO' is given
                                              external name `foo_'.
* Multiple Definitions of External Names::  No doing both `COMMON /FOO/'
                                              and `SUBROUTINE FOO'.
* Limitation on Implicit Declarations::     No `IMPLICIT CHARACTER*(*)'.


File: g77.info,  Node: Mangling of Names,  Next: Multiple Definitions of External Names,  Up: Disappointments

15.4.1 Mangling of Names in Source Code
---------------------------------------

The current external-interface design, which includes naming of
external procedures, COMMON blocks, and the library interface, has
various usability problems, including things like adding underscores
where not really necessary (and preventing easier inter-language
operability) and yet not providing complete namespace freedom for user
C code linked with Fortran apps (due to the naming of functions in the
library, among other things).

   Project GNU should at least get all this "right" for systems it
fully controls, such as the Hurd, and provide defaults and options for
compatibility with existing systems and interoperability with popular
existing compilers.


File: g77.info,  Node: Multiple Definitions of External Names,  Next: Limitation on Implicit Declarations,  Prev: Mangling of Names,  Up: Disappointments

15.4.2 Multiple Definitions of External Names
---------------------------------------------

`g77' doesn't allow a common block and an external procedure or `BLOCK
DATA' to have the same name.  Some systems allow this, but `g77' does
not, to be compatible with `f2c'.

   `g77' could special-case the way it handles `BLOCK DATA', since it
is not compatible with `f2c' in this particular area (necessarily,
since `g77' offers an important feature here), but it is likely that
such special-casing would be very annoying to people with programs that
use `EXTERNAL FOO', with no other mention of `FOO' in the same program
unit, to refer to external procedures, since the result would be that
`g77' would treat these references as requests to force-load BLOCK DATA
program units.

   In that case, if `g77' modified names of `BLOCK DATA' so they could
have the same names as `COMMON', users would find that their programs
wouldn't link because the `FOO' procedure didn't have its name
translated the same way.

   (Strictly speaking, `g77' could emit a
null-but-externally-satisfying definition of `FOO' with its name
transformed as if it had been a `BLOCK DATA', but that probably invites
more trouble than it's worth.)


File: g77.info,  Node: Limitation on Implicit Declarations,  Prev: Multiple Definitions of External Names,  Up: Disappointments

15.4.3 Limitation on Implicit Declarations
------------------------------------------

`g77' disallows `IMPLICIT CHARACTER*(*)'.  This is not
standard-conforming.


File: g77.info,  Node: Non-bugs,  Next: Warnings and Errors,  Prev: Disappointments,  Up: Trouble

15.5 Certain Changes We Don't Want to Make
==========================================

This section lists changes that people frequently request, but which we
do not make because we think GNU Fortran is better without them.

* Menu:

* Backslash in Constants::           Why `'\\'' is a constant that
                                       is one, not two, characters long.
* Initializing Before Specifying::   Why `DATA VAR/1/' can't precede
                                       `COMMON VAR'.
* Context-Sensitive Intrinsicness::  Why `CALL SQRT' won't work.
* Context-Sensitive Constants::      Why `9.435784839284958' is a
                                       single-precision constant,
                                       and might be interpreted as
                                       `9.435785' or similar.
* Equivalence Versus Equality::      Why `.TRUE. .EQ. .TRUE.' won't work.
* Order of Side Effects::            Why `J = IFUNC() - IFUNC()' might
                                       not behave as expected.


File: g77.info,  Node: Backslash in Constants,  Next: Initializing Before Specifying,  Up: Non-bugs

15.5.1 Backslash in Constants
-----------------------------

In the opinion of many experienced Fortran users, `-fno-backslash'
should be the default, not `-fbackslash', as currently set by `g77'.

   First of all, you can always specify `-fno-backslash' to turn off
this processing.

   Despite not being within the spirit (though apparently within the
letter) of the ANSI FORTRAN 77 standard, `g77' defaults to
`-fbackslash' because that is what most UNIX `f77' commands default to,
and apparently lots of code depends on this feature.

   This is a particularly troubling issue.  The use of a C construct in
the midst of Fortran code is bad enough, worse when it makes existing
Fortran programs stop working (as happens when programs written for
non-UNIX systems are ported to UNIX systems with compilers that provide
the `-fbackslash' feature as the default--sometimes with no option to
turn it off).

   The author of GNU Fortran wished, for reasons of linguistic purity,
to make `-fno-backslash' the default for GNU Fortran and thus require
users of UNIX `f77' and `f2c' to specify `-fbackslash' to get the UNIX
behavior.

   However, the realization that `g77' is intended as a replacement for
_UNIX_ `f77', caused the author to choose to make `g77' as compatible
with `f77' as feasible, which meant making `-fbackslash' the default.

   The primary focus on compatibility is at the source-code level, and
the question became "What will users expect a replacement for `f77' to
do, by default?"  Although at least one UNIX `f77' does not provide
`-fbackslash' as a default, it appears that the majority of them do,
which suggests that the majority of code that is compiled by UNIX `f77'
compilers expects `-fbackslash' to be the default.

   It is probably the case that more code exists that would _not_ work
with `-fbackslash' in force than code that requires it be in force.

   However, most of _that_ code is not being compiled with `f77', and
when it is, new build procedures (shell scripts, makefiles, and so on)
must be set up anyway so that they work under UNIX.  That makes a much
more natural and safe opportunity for non-UNIX users to adapt their
build procedures for `g77''s default of `-fbackslash' than would exist
for the majority of UNIX `f77' users who would have to modify existing,
working build procedures to explicitly specify `-fbackslash' if that was
not the default.

   One suggestion has been to configure the default for `-fbackslash'
(and perhaps other options as well) based on the configuration of `g77'.

   This is technically quite straightforward, but will be avoided even
in cases where not configuring defaults to be dependent on a particular
configuration greatly inconveniences some users of legacy code.

   Many users appreciate the GNU compilers because they provide an
environment that is uniform across machines.  These users would be
inconvenienced if the compiler treated things like the format of the
source code differently on certain machines.

   Occasionally users write programs intended only for a particular
machine type.  On these occasions, the users would benefit if the GNU
Fortran compiler were to support by default the same dialect as the
other compilers on that machine.  But such applications are rare.  And
users writing a program to run on more than one type of machine cannot
possibly benefit from this kind of compatibility.  (This is consistent
with the design goals for `gcc'.  To change them for `g77', you must
first change them for `gcc'.  Do not ask the maintainers of `g77' to do
this for you, or to disassociate `g77' from the widely understood, if
not widely agreed-upon, goals for GNU compilers in general.)

   This is why GNU Fortran does and will treat backslashes in the same
fashion on all types of machines (by default).  *Note Direction of
Language Development::, for more information on this overall philosophy
guiding the development of the GNU Fortran language.

   Of course, users strongly concerned about portability should indicate
explicitly in their build procedures which options are expected by
their source code, or write source code that has as few such
expectations as possible.

   For example, avoid writing code that depends on backslash (`\')
being interpreted either way in particular, such as by starting a
program unit with:

     CHARACTER BACKSL
     PARAMETER (BACKSL = '\\')

Then, use concatenation of `BACKSL' anyplace a backslash is desired.
In this way, users can write programs which have the same meaning in
many Fortran dialects.

   (However, this technique does not work for Hollerith constants--which
is just as well, since the only generally portable uses for Hollerith
constants are in places where character constants can and should be
used instead, for readability.)


File: g77.info,  Node: Initializing Before Specifying,  Next: Context-Sensitive Intrinsicness,  Prev: Backslash in Constants,  Up: Non-bugs

15.5.2 Initializing Before Specifying
-------------------------------------

`g77' does not allow `DATA VAR/1/' to appear in the source code before
`COMMON VAR', `DIMENSION VAR(10)', `INTEGER VAR', and so on.  In
general, `g77' requires initialization of a variable or array to be
specified _after_ all other specifications of attributes (type, size,
placement, and so on) of that variable or array are specified (though
_confirmation_ of data type is permitted).

   It is _possible_ `g77' will someday allow all of this, even though
it is not allowed by the FORTRAN 77 standard.

   Then again, maybe it is better to have `g77' always require
placement of `DATA' so that it can possibly immediately write constants
to the output file, thus saving time and space.

   That is, `DATA A/1000000*1/' should perhaps always be immediately
writable to canonical assembler, unless it's already known to be in a
`COMMON' area following as-yet-uninitialized stuff, and to do this it
cannot be followed by `COMMON A'.


File: g77.info,  Node: Context-Sensitive Intrinsicness,  Next: Context-Sensitive Constants,  Prev: Initializing Before Specifying,  Up: Non-bugs

15.5.3 Context-Sensitive Intrinsicness
--------------------------------------

`g77' treats procedure references to _possible_ intrinsic names as
always enabling their intrinsic nature, regardless of whether the
_form_ of the reference is valid for that intrinsic.

   For example, `CALL SQRT' is interpreted by `g77' as an invalid
reference to the `SQRT' intrinsic function, because the reference is a
subroutine invocation.

   First, `g77' recognizes the statement `CALL SQRT' as a reference to
a _procedure_ named `SQRT', not to a _variable_ with that name (as it
would for a statement such as `V = SQRT').

   Next, `g77' establishes that, in the program unit being compiled,
`SQRT' is an intrinsic--not a subroutine that happens to have the same
name as an intrinsic (as would be the case if, for example, `EXTERNAL
SQRT' was present).

   Finally, `g77' recognizes that the _form_ of the reference is
invalid for that particular intrinsic.  That is, it recognizes that it
is invalid for an intrinsic _function_, such as `SQRT', to be invoked as
a _subroutine_.

   At that point, `g77' issues a diagnostic.

   Some users claim that it is "obvious" that `CALL SQRT' references an
external subroutine of their own, not an intrinsic function.

   However, `g77' knows about intrinsic subroutines, not just
functions, and is able to support both having the same names, for
example.

   As a result of this, `g77' rejects calls to intrinsics that are not
subroutines, and function invocations of intrinsics that are not
functions, just as it (and most compilers) rejects invocations of
intrinsics with the wrong number (or types) of arguments.

   So, use the `EXTERNAL SQRT' statement in a program unit that calls a
user-written subroutine named `SQRT'.


File: g77.info,  Node: Context-Sensitive Constants,  Next: Equivalence Versus Equality,  Prev: Context-Sensitive Intrinsicness,  Up: Non-bugs

15.5.4 Context-Sensitive Constants
----------------------------------

`g77' does not use context to determine the types of constants or named
constants (`PARAMETER'), except for (non-standard) typeless constants
such as `'123'O'.

   For example, consider the following statement:

     PRINT *, 9.435784839284958 * 2D0

`g77' will interpret the (truncated) constant `9.435784839284958' as a
`REAL(KIND=1)', not `REAL(KIND=2)', constant, because the suffix `D0'
is not specified.

   As a result, the output of the above statement when compiled by
`g77' will appear to have "less precision" than when compiled by other
compilers.

   In these and other cases, some compilers detect the fact that a
single-precision constant is used in a double-precision context and
therefore interpret the single-precision constant as if it was
_explicitly_ specified as a double-precision constant.  (This has the
effect of appending _decimal_, not _binary_, zeros to the fractional
part of the number--producing different computational results.)

   The reason this misfeature is dangerous is that a slight, apparently
innocuous change to the source code can change the computational
results.  Consider:

     REAL ALMOST, CLOSE
     DOUBLE PRECISION FIVE
     PARAMETER (ALMOST = 5.000000000001)
     FIVE = 5
     CLOSE = 5.000000000001
     PRINT *, 5.000000000001 - FIVE
     PRINT *, ALMOST - FIVE
     PRINT *, CLOSE - FIVE
     END

Running the above program should result in the same value being printed
three times.  With `g77' as the compiler, it does.

   However, compiled by many other compilers, running the above program
would print two or three distinct values, because in two or three of
the statements, the constant `5.000000000001', which on most systems is
exactly equal to `5.' when interpreted as a single-precision constant,
is instead interpreted as a double-precision constant, preserving the
represented precision.  However, this "clever" promotion of type does
not extend to variables or, in some compilers, to named constants.

   Since programmers often are encouraged to replace manifest constants
or permanently-assigned variables with named constants (`PARAMETER' in
Fortran), and might need to replace some constants with variables
having the same values for pertinent portions of code, it is important
that compilers treat code so modified in the same way so that the
results of such programs are the same.  `g77' helps in this regard by
treating constants just the same as variables in terms of determining
their types in a context-independent way.

   Still, there is a lot of existing Fortran code that has been written
to depend on the way other compilers freely interpret constants' types
based on context, so anything `g77' can do to help flag cases of this
in such code could be very helpful.


File: g77.info,  Node: Equivalence Versus Equality,  Next: Order of Side Effects,  Prev: Context-Sensitive Constants,  Up: Non-bugs

15.5.5 Equivalence Versus Equality
----------------------------------

Use of `.EQ.' and `.NE.' on `LOGICAL' operands is not supported, except
via `-fugly-logint', which is not recommended except for legacy code
(where the behavior expected by the _code_ is assumed).

   Legacy code should be changed, as resources permit, to use `.EQV.'
and `.NEQV.' instead, as these are permitted by the various Fortran
standards.

   New code should never be written expecting `.EQ.' or `.NE.' to work
if either of its operands is `LOGICAL'.

   The problem with supporting this "feature" is that there is unlikely
to be consensus on how it works, as illustrated by the following sample
program:

     LOGICAL L,M,N
     DATA L,M,N /3*.FALSE./
     IF (L.AND.M.EQ.N) PRINT *,'L.AND.M.EQ.N'
     END

   The issue raised by the above sample program is: what is the
precedence of `.EQ.' (and `.NE.') when applied to `LOGICAL' operands?

   Some programmers will argue that it is the same as the precedence
for `.EQ.' when applied to numeric (such as `INTEGER') operands.  By
this interpretation, the subexpression `M.EQ.N' must be evaluated first
in the above program, resulting in a program that, when run, does not
execute the `PRINT' statement.

   Other programmers will argue that the precedence is the same as the
precedence for `.EQV.', which is restricted by the standards to
`LOGICAL' operands.  By this interpretation, the subexpression
`L.AND.M' must be evaluated first, resulting in a program that _does_
execute the `PRINT' statement.

   Assigning arbitrary semantic interpretations to syntactic expressions
that might legitimately have more than one "obvious" interpretation is
generally unwise.

   The creators of the various Fortran standards have done a good job
in this case, requiring a distinct set of operators (which have their
own distinct precedence) to compare `LOGICAL' operands.  This
requirement results in expression syntax with more certain precedence
(without requiring substantial context), making it easier for
programmers to read existing code.  `g77' will avoid muddying up
elements of the Fortran language that were well-designed in the first
place.

   (Ask C programmers about the precedence of expressions such as `(a)
& (b)' and `(a) - (b)'--they cannot even tell you, without knowing more
context, whether the `&' and `-' operators are infix (binary) or unary!)

   Most dangerous of all is the fact that, even assuming consensus on
its meaning, an expression like `L.AND.M.EQ.N', if it is the result of
a typographical error, doesn't _look_ like it has such a typo.  Even
experienced Fortran programmers would not likely notice that
`L.AND.M.EQV.N' was, in fact, intended.

   So, this is a prime example of a circumstance in which a quality
compiler diagnoses the code, instead of leaving it up to someone
debugging it to know to turn on special compiler options that might
diagnose it.


File: g77.info,  Node: Order of Side Effects,  Prev: Equivalence Versus Equality,  Up: Non-bugs

15.5.6 Order of Side Effects
----------------------------

`g77' does not necessarily produce code that, when run, performs side
effects (such as those performed by function invocations) in the same
order as in some other compiler--or even in the same order as another
version, port, or invocation (using different command-line options) of
`g77'.

   It is never safe to depend on the order of evaluation of side
effects.  For example, an expression like this may very well behave
differently from one compiler to another:

     J = IFUNC() - IFUNC()

There is no guarantee that `IFUNC' will be evaluated in any particular
order.  Either invocation might happen first.  If `IFUNC' returns 5 the
first time it is invoked, and returns 12 the second time, `J' might end
up with the value `7', or it might end up with `-7'.

   Generally, in Fortran, procedures with side-effects intended to be
visible to the caller are best designed as _subroutines_, not functions.
Examples of such side-effects include:

   * The generation of random numbers that are intended to influence
     return values.

   * Performing I/O (other than internal I/O to local variables).

   * Updating information in common blocks.

   An example of a side-effect that is not intended to be visible to
the caller is a function that maintains a cache of recently calculated
results, intended solely to speed repeated invocations of the function
with identical arguments.  Such a function can be safely used in
expressions, because if the compiler optimizes away one or more calls
to the function, operation of the program is unaffected (aside from
being speeded up).


File: g77.info,  Node: Warnings and Errors,  Prev: Non-bugs,  Up: Trouble

15.6 Warning Messages and Error Messages
========================================

The GNU compiler can produce two kinds of diagnostics: errors and
warnings.  Each kind has a different purpose:

     _Errors_ report problems that make it impossible to compile your
     program.  GNU Fortran reports errors with the source file name,
     line number, and column within the line where the problem is
     apparent.

     _Warnings_ report other unusual conditions in your code that
     _might_ indicate a problem, although compilation can (and does)
     proceed.  Warning messages also report the source file name, line
     number, and column information, but include the text `warning:' to
     distinguish them from error messages.

   Warnings might indicate danger points where you should check to make
sure that your program really does what you intend; or the use of
obsolete features; or the use of nonstandard features of GNU Fortran.
Many warnings are issued only if you ask for them, with one of the `-W'
options (for instance, `-Wall' requests a variety of useful warnings).

   _Note:_ Currently, the text of the line and a pointer to the column
is printed in most `g77' diagnostics.

   *Note Options to Request or Suppress Warnings: Warning Options, for
more detail on these and related command-line options.


File: g77.info,  Node: Open Questions,  Next: Bugs,  Prev: Trouble,  Up: Top

16 Open Questions
*****************

Please consider offering useful answers to these questions!

   * `LOC()' and other intrinsics are probably somewhat misclassified.
     Is the a need for more precise classification of intrinsics, and
     if so, what are the appropriate groupings?  Is there a need to
     individually enable/disable/delete/hide intrinsics from the
     command line?


File: g77.info,  Node: Bugs,  Next: Service,  Prev: Open Questions,  Up: Top

17 Reporting Bugs
*****************

Your bug reports play an essential role in making GNU Fortran reliable.

   When you encounter a problem, the first thing to do is to see if it
is already known.  *Note Trouble::.  If it isn't known, then you should
report the problem.

* Menu:

* Criteria: Bug Criteria.    Have you really found a bug?
* Reporting: Bug Reporting.  How to report a bug effectively.

   *Note Known Causes of Trouble with GNU Fortran: Trouble, for
information on problems we already know about.

   *Note How To Get Help with GNU Fortran: Service, for information on
where to ask for help.


File: g77.info,  Node: Bug Criteria,  Next: Bug Reporting,  Up: Bugs

17.1 Have You Found a Bug?
==========================

If you are not sure whether you have found a bug, here are some
guidelines:

   * If the compiler gets a fatal signal, for any input whatever, that
     is a compiler bug.  Reliable compilers never crash--they just
     remain obsolete.

   * If the compiler produces invalid assembly code, for any input
     whatever, that is a compiler bug, unless the compiler reports
     errors (not just warnings) which would ordinarily prevent the
     assembler from being run.

   * If the compiler produces valid assembly code that does not
     correctly execute the input source code, that is a compiler bug.

     However, you must double-check to make sure, because you might
     have run into an incompatibility between GNU Fortran and
     traditional Fortran.  These incompatibilities might be considered
     bugs, but they are inescapable consequences of valuable features.

     Or you might have a program whose behavior is undefined, which
     happened by chance to give the desired results with another
     Fortran compiler.  It is best to check the relevant Fortran
     standard thoroughly if it is possible that the program indeed does
     something undefined.

     After you have localized the error to a single source line, it
     should be easy to check for these things.  If your program is
     correct and well defined, you have found a compiler bug.

     It might help if, in your submission, you identified the specific
     language in the relevant Fortran standard that specifies the
     desired behavior, if it isn't likely to be obvious and agreed-upon
     by all Fortran users.

   * If the compiler produces an error message for valid input, that is
     a compiler bug.

   * If the compiler does not produce an error message for invalid
     input, that is a compiler bug.  However, you should note that your
     idea of "invalid input" might be someone else's idea of "an
     extension" or "support for traditional practice".

   * If you are an experienced user of Fortran compilers, your
     suggestions for improvement of GNU Fortran are welcome in any case.

   Many, perhaps most, bug reports against `g77' turn out to be bugs in
the user's code.  While we find such bug reports educational, they
sometimes take a considerable amount of time to track down or at least
respond to--time we could be spending making `g77', not some user's
code, better.

   Some steps you can take to verify that the bug is not certainly in
the code you're compiling with `g77':

   * Compile your code using the `g77' options `-W -Wall -O'.  These
     options enable many useful warning; the `-O' option enables flow
     analysis that enables the uninitialized-variable warning.

     If you investigate the warnings and find evidence of possible bugs
     in your code, fix them first and retry `g77'.

   * Compile your code using the `g77' options `-finit-local-zero',
     `-fno-automatic', `-ffloat-store', and various combinations
     thereof.

     If your code works with any of these combinations, that is not
     proof that the bug isn't in `g77'--a `g77' bug exposed by your
     code might simply be avoided, or have a different, more subtle
     effect, when different options are used--but it can be a strong
     indicator that your code is making unwarranted assumptions about
     the Fortran dialect and/or underlying machine it is being compiled
     and run on.

     *Note Overly Convenient Command-Line Options: Overly Convenient
     Options, for information on the `-fno-automatic' and
     `-finit-local-zero' options and how to convert their use into
     selective changes in your own code.

   * Validate your code with `ftnchek' or a similar code-checking tool.
     `ftnchek' can be found at `ftp://ftp.netlib.org/fortran' or
     `ftp://ftp.dsm.fordham.edu'.

     Here are some sample `Makefile' rules using `ftnchek' "project"
     files to do cross-file checking and `sfmakedepend' (from
     `ftp://ahab.rutgers.edu/pub/perl/sfmakedepend') to maintain
     dependencies automatically.  These assume the use of GNU `make'.

          # Dummy suffix for ftnchek targets:
          .SUFFIXES: .chek
          .PHONY: chekall

          # How to compile .f files (for implicit rule):
          FC = g77
          # Assume `include' directory:
          FFLAGS = -Iinclude -g -O -Wall

          # Flags for ftnchek:
          CHEK1 = -array=0 -include=includes -noarray
          CHEK2 = -nonovice -usage=1 -notruncation
          CHEKFLAGS = $(CHEK1) $(CHEK2)

          # Run ftnchek with all the .prj files except the one corresponding
          # to the target's root:
          %.chek : %.f ; \
            ftnchek $(filter-out $*.prj,$(PRJS)) $(CHEKFLAGS) \
              -noextern -library $<

          # Derive a project file from a source file:
          %.prj : %.f ; \
            ftnchek $(CHEKFLAGS) -noextern -project -library $<

          # The list of objects is assumed to be in variable OBJS.
          # Sources corresponding to the objects:
          SRCS = $(OBJS:%.o=%.f)
          # ftnchek project files:
          PRJS = $(OBJS:%.o=%.prj)

          # Build the program
          prog: $(OBJS) ; \
            $(FC) -o $ $(OBJS)

          chekall: $(PRJS) ; \
            ftnchek $(CHEKFLAGS) $(PRJS)

          prjs: $(PRJS)

          # For Emacs M-x find-tag:
          TAGS: $(SRCS) ; \
            etags $(SRCS)

          # Rebuild dependencies:
          depend: ; \
            sfmakedepend -I $(PLTLIBDIR) -I includes -a prj $(SRCS1)

   * Try your code out using other Fortran compilers, such as `f2c'.
     If it does not work on at least one other compiler (assuming the
     compiler supports the features the code needs), that is a strong
     indicator of a bug in the code.

     However, even if your code works on many compilers _except_ `g77',
     that does _not_ mean the bug is in `g77'.  It might mean the bug
     is in your code, and that `g77' simply exposes it more readily
     than other compilers.


File: g77.info,  Node: Bug Reporting,  Prev: Bug Criteria,  Up: Bugs

17.2 How to Report Bugs
=======================

Bugs should be reported to our bug database.  Please refer to
`http://gcc.gnu.org/bugs.html' for up-to-date instructions how to
submit bug reports.  Copies of this file in HTML (`bugs.html') and
plain text (`BUGS') are also part of GCC releases.


File: g77.info,  Node: Service,  Next: Adding Options,  Prev: Bugs,  Up: Top

18 How To Get Help with GNU Fortran
***********************************

If you need help installing, using or changing GNU Fortran, there are
two ways to find it:

   * Look in the service directory for someone who might help you for a
     fee.  The service directory is found in the file named `SERVICE'
     in the GNU CC distribution.

   * Send a message to <gcc-help@gcc.gnu.org>.


File: g77.info,  Node: Adding Options,  Next: Projects,  Prev: Service,  Up: Top

19 Adding Options
*****************

To add a new command-line option to `g77', first decide what kind of
option you wish to add.  Search the `g77' and `gcc' documentation for
one or more options that is most closely like the one you want to add
(in terms of what kind of effect it has, and so on) to help clarify its
nature.

   * _Fortran options_ are options that apply only when compiling
     Fortran programs.  They are accepted by `g77' and `gcc', but they
     apply only when compiling Fortran programs.

   * _Compiler options_ are options that apply when compiling most any
     kind of program.

   _Fortran options_ are listed in the file `gcc/gcc/f/lang-options.h',
which is used during the build of `gcc' to build a list of all options
that are accepted by at least one language's compiler.  This list goes
into the `documented_lang_options' array in `gcc/toplev.c', which uses
this array to determine whether a particular option should be offered
to the linked-in front end for processing by calling
`lang_option_decode', which, for `g77', is in `gcc/gcc/f/com.c' and just
calls `ffe_decode_option'.

   If the linked-in front end "rejects" a particular option passed to
it, `toplev.c' just ignores the option, because _some_ language's
compiler is willing to accept it.

   This allows commands like `gcc -fno-asm foo.c bar.f' to work, even
though Fortran compilation does not currently support the `-fno-asm'
option; even though the `f771' version of `lang_decode_option' rejects
`-fno-asm', `toplev.c' doesn't produce a diagnostic because some other
language (C) does accept it.

   This also means that commands like `g77 -fno-asm foo.f' yield no
diagnostics, despite the fact that no phase of the command was able to
recognize and process `-fno-asm'--perhaps a warning about this would be
helpful if it were possible.

   Code that processes Fortran options is found in `gcc/gcc/f/top.c',
function `ffe_decode_option'.  This code needs to check positive and
negative forms of each option.

   The defaults for Fortran options are set in their global
definitions, also found in `gcc/gcc/f/top.c'.  Many of these defaults
are actually macros defined in `gcc/gcc/f/target.h', since they might be
machine-specific.  However, since, in practice, GNU compilers should
behave the same way on all configurations (especially when it comes to
language constructs), the practice of setting defaults in `target.h' is
likely to be deprecated and, ultimately, stopped in future versions of
`g77'.

   Accessor macros for Fortran options, used by code in the `g77' FFE,
are defined in `gcc/gcc/f/top.h'.

   _Compiler options_ are listed in `gcc/toplev.c' in the array
`f_options'.  An option not listed in `lang_options' is looked up in
`f_options' and handled from there.

   The defaults for compiler options are set in the global definitions
for the corresponding variables, some of which are in `gcc/toplev.c'.

   You can set different defaults for _Fortran-oriented_ or
_Fortran-reticent_ compiler options by changing the source code of
`g77' and rebuilding.  How to do this depends on the version of `g77':

`G77 0.5.24 (EGCS 1.1)'
`G77 0.5.25 (EGCS 1.2 - which became GCC 2.95)'
     Change the `lang_init_options' routine in `gcc/gcc/f/com.c'.

     (Note that these versions of `g77' perform internal consistency
     checking automatically when the `-fversion' option is specified.)

`G77 0.5.23'
`G77 0.5.24 (EGCS 1.0)'
     Change the way `f771' handles the `-fset-g77-defaults' option,
     which is always provided as the first option when called by `g77'
     or `gcc'.

     This code is in `ffe_decode_options' in `gcc/gcc/f/top.c'.  Have
     it change just the variables that you want to default to a
     different setting for Fortran compiles compared to compiles of
     other languages.

     The `-fset-g77-defaults' option is passed to `f771' automatically
     because of the specification information kept in
     `gcc/gcc/f/lang-specs.h'.  This file tells the `gcc' command how
     to recognize, in this case, Fortran source files (those to be
     preprocessed, and those that are not), and further, how to invoke
     the appropriate programs (including `f771') to process those
     source files.

     It is in `gcc/gcc/f/lang-specs.h' that `-fset-g77-defaults',
     `-fversion', and other options are passed, as appropriate, even
     when the user has not explicitly specified them.  Other "internal"
     options such as `-quiet' also are passed via this mechanism.


File: g77.info,  Node: Projects,  Next: Front End,  Prev: Adding Options,  Up: Top

20 Projects
***********

If you want to contribute to `g77' by doing research, design,
specification, documentation, coding, or testing, the following
information should give you some ideas.

* Menu:

* Efficiency::               Make `g77' itself compile code faster.
* Better Optimization::      Teach `g77' to generate faster code.
* Simplify Porting::         Make `g77' easier to configure, build,
                             and install.
* More Extensions::          Features many users won't know to ask for.
* Machine Model::            `g77' should better leverage `gcc'.
* Internals Documentation::  Make maintenance easier.
* Internals Improvements::   Make internals more robust.
* Better Diagnostics::       Make using `g77' on new code easier.


File: g77.info,  Node: Efficiency,  Next: Better Optimization,  Up: Projects

20.1 Improve Efficiency
=======================

Don't bother doing any performance analysis until most of the following
items are taken care of, because there's no question they represent
serious space/time problems, although some of them show up only given
certain kinds of (popular) input.

   * Improve `malloc' package and its uses to specify more info about
     memory pools and, where feasible, use obstacks to implement them.

   * Skip over uninitialized portions of aggregate areas (arrays,
     `COMMON' areas, `EQUIVALENCE' areas) so zeros need not be output.
     This would reduce memory usage for large initialized aggregate
     areas, even ones with only one initialized element.

     As of version 0.5.18, a portion of this item has already been
     accomplished.

   * Prescan the statement (in `sta.c') so that the nature of the
     statement is determined as much as possible by looking entirely at
     its form, and not looking at any context (previous statements,
     including types of symbols).  This would allow ripping out of the
     statement-confirmation, symbol retraction/confirmation, and
     diagnostic inhibition mechanisms.  Plus, it would result in
     much-improved diagnostics.  For example, `CALL
     some-intrinsic(...)', where the intrinsic is not a subroutine
     intrinsic, would result actual error instead of the
     unimplemented-statement catch-all.

   * Throughout `g77', don't pass line/column pairs where a simple
     `ffewhere' type, which points to the error as much as is desired
     by the configuration, will do, and don't pass `ffelexToken' types
     where a simple `ffewhere' type will do.  Then, allow new default
     configuration of `ffewhere' such that the source line text is not
     preserved, and leave it to things like Emacs' next-error function
     to point to them (now that `next-error' supports column, or,
     perhaps, character-offset, numbers).  The change in calling
     sequences should improve performance somewhat, as should not
     having to save source lines.  (Whether this whole item will
     improve performance is questionable, but it should improve
     maintainability.)

   * Handle `DATA (A(I),I=1,1000000)/1000000*2/' more efficiently,
     especially as regards the assembly output.  Some of this might
     require improving the back end, but lots of improvement in
     space/time required in `g77' itself can be fairly easily obtained
     without touching the back end.  Maybe type-conversion, where
     necessary, can be speeded up as well in cases like the one shown
     (converting the `2' into `2.').

   * If analysis shows it to be worthwhile, optimize `lex.c'.

   * Consider redesigning `lex.c' to not need any feedback during
     tokenization, by keeping track of enough parse state on its own.


File: g77.info,  Node: Better Optimization,  Next: Simplify Porting,  Prev: Efficiency,  Up: Projects

20.2 Better Optimization
========================

Much of this work should be put off until after `g77' has all the
features necessary for its widespread acceptance as a useful F77
compiler.  However, perhaps this work can be done in parallel during
the feature-adding work.

   * Do the equivalent of the trick of putting `extern inline' in front
     of every function definition in `libg2c' and #include'ing the
     resulting file in `f2c'+`gcc'--that is, inline all
     run-time-library functions that are at all worth inlining.  (Some
     of this has already been done, such as for integral
     exponentiation.)

   * When doing `CHAR_VAR = CHAR_FUNC(...)', and it's clear that types
     line up and `CHAR_VAR' is addressable or not a `VAR_DECL', make
     `CHAR_VAR', not a temporary, be the receiver for `CHAR_FUNC'.
     (This is now done for `COMPLEX' variables.)

   * Design and implement Fortran-specific optimizations that don't
     really belong in the back end, or where the front end needs to
     give the back end more info than it currently does.

   * Design and implement a new run-time library interface, with the
     code going into `libgcc' so no special linking is required to link
     Fortran programs using standard language features.  This library
     would speed up lots of things, from I/O (using precompiled formats,
     doing just one, or, at most, very few, calls for arrays or array
     sections, and so on) to general computing (array/section
     implementations of various intrinsics, implementation of commonly
     performed loops that aren't likely to be optimally compiled
     otherwise, etc.).

     Among the important things the library would do are:

        * Be a one-stop-shop-type library, hence shareable and usable
          by all, in that what are now library-build-time options in
          `libg2c' would be moved at least to the `g77' compile phase,
          if not to finer grains (such as choosing how list-directed
          I/O formatting is done by default at `OPEN' time, for
          preconnected units via options or even statements in the main
          program unit, maybe even on a per-I/O basis with appropriate
          pragma-like devices).

   * Probably requiring the new library design, change interface to
     normally have `COMPLEX' functions return their values in the way
     `gcc' would if they were declared `__complex__ float', rather than
     using the mechanism currently used by `CHARACTER' functions
     (whereby the functions are compiled as returning void and their
     first arg is a pointer to where to store the result).  (Don't
     append underscores to external names for `COMPLEX' functions in
     some cases once `g77' uses `gcc' rather than `f2c' calling
     conventions.)

   * Do something useful with `doiter' references where possible.  For
     example, `CALL FOO(I)' cannot modify `I' if within a `DO' loop
     that uses `I' as the iteration variable, and the back end might
     find that info useful in determining whether it needs to read `I'
     back into a register after the call.  (It normally has to do that,
     unless it knows `FOO' never modifies its passed-by-reference
     argument, which is rarely the case for Fortran-77 code.)


File: g77.info,  Node: Simplify Porting,  Next: More Extensions,  Prev: Better Optimization,  Up: Projects

20.3 Simplify Porting
=====================

Making `g77' easier to configure, port, build, and install, either as a
single-system compiler or as a cross-compiler, would be very useful.

   * A new library (replacing `libg2c') should improve portability as
     well as produce more optimal code.  Further, `g77' and the new
     library should conspire to simplify naming of externals, such as
     by removing unnecessarily added underscores, and to
     reduce/eliminate the possibility of naming conflicts, while making
     debugger more straightforward.

     Also, it should make multi-language applications more feasible,
     such as by providing Fortran intrinsics that get Fortran unit
     numbers given C `FILE *' descriptors.

   * Possibly related to a new library, `g77' should produce the
     equivalent of a `gcc' `main(argc, argv)' function when it compiles
     a main program unit, instead of compiling something that must be
     called by a library implementation of `main()'.

     This would do many useful things such as provide more flexibility
     in terms of setting up exception handling, not requiring
     programmers to start their debugging sessions with `breakpoint
     MAIN__' followed by `run', and so on.

   * The GBE needs to understand the difference between alignment
     requirements and desires.  For example, on Intel x86 machines,
     `g77' currently imposes overly strict alignment requirements, due
     to the back end, but it would be useful for Fortran and C
     programmers to be able to override these _recommendations_ as long
     as they don't violate the actual processor _requirements_.


File: g77.info,  Node: More Extensions,  Next: Machine Model,  Prev: Simplify Porting,  Up: Projects

20.4 More Extensions
====================

These extensions are not the sort of things users ask for "by name",
but they might improve the usability of `g77', and Fortran in general,
in the long run.  Some of these items really pertain to improving `g77'
internals so that some popular extensions can be more easily supported.

   * Look through all the documentation on the GNU Fortran language,
     dialects, compiler, missing features, bugs, and so on.  Many
     mentions of incomplete or missing features are sprinkled
     throughout.  It is not worth repeating them here.

   * Consider adding a `NUMERIC' type to designate typeless numeric
     constants, named and unnamed.  The idea is to provide a
     forward-looking, effective replacement for things like the
     old-style `PARAMETER' statement when people really need
     typelessness in a maintainable, portable, clearly documented way.
     Maybe `TYPELESS' would include `CHARACTER', `POINTER', and
     whatever else might come along.  (This is not really a call for
     polymorphism per se, just an ability to express limited, syntactic
     polymorphism.)

   * Support `OPEN(...,KEY=(...),...)'.

   * Support arbitrary file unit numbers, instead of limiting them to 0
     through `MXUNIT-1'.  (This is a `libg2c' issue.)

   * `OPEN(NOSPANBLOCKS,...)' is treated as
     `OPEN(UNIT=NOSPANBLOCKS,...)', so a later `UNIT=' in the first
     example is invalid.  Make sure this is what users of this feature
     would expect.

   * Currently `g77' disallows `READ(1'10)' since it is an obnoxious
     syntax, but supporting it might be pretty easy if needed.  More
     details are needed, such as whether general expressions separated
     by an apostrophe are supported, or maybe the record number can be
     a general expression, and so on.

   * Support `STRUCTURE', `UNION', `MAP', and `RECORD' fully.
     Currently there is no support at all for `%FILL' in `STRUCTURE'
     and related syntax, whereas the rest of the stuff has at least
     some parsing support.  This requires either major changes to
     `libg2c' or its replacement.

   * F90 and `g77' probably disagree about label scoping relative to
     `INTERFACE' and `END INTERFACE', and their contained procedure
     interface bodies (blocks?).

   * `ENTRY' doesn't support F90 `RESULT()' yet, since that was added
     after S8.112.

   * Empty-statement handling (10 ;;CONTINUE;;) probably isn't
     consistent with the final form of the standard (it was vague at
     S8.112).

   * It seems to be an "open" question whether a file, immediately
     after being `OPEN'ed,is positioned at the beginning, the end, or
     wherever--it might be nice to offer an option of opening to
     "undefined" status, requiring an explicit absolute-positioning
     operation to be performed before any other (besides `CLOSE') to
     assist in making applications port to systems (some IBM?) that
     `OPEN' to the end of a file or some such thing.


File: g77.info,  Node: Machine Model,  Next: Internals Documentation,  Prev: More Extensions,  Up: Projects

20.5 Machine Model
==================

This items pertain to generalizing `g77''s view of the machine model to
more fully accept whatever the GBE provides it via its configuration.

   * Switch to using `REAL_VALUE_TYPE' to represent floating-point
     constants exclusively so the target float format need not be
     required.  This means changing the way `g77' handles
     initialization of aggregate areas having more than one type, such
     as `REAL' and `INTEGER', because currently it initializes them as
     if they were arrays of `char' and uses the bit patterns of the
     constants of the various types in them to determine what to stuff
     in elements of the arrays.

   * Rely more and more on back-end info and capabilities, especially
     in the area of constants (where having the `g77' front-end's IL
     just store the appropriate tree nodes containing constants might
     be best).

   * Suite of C and Fortran programs that a user/administrator can run
     on a machine to help determine the configuration for `g77' before
     building and help determine if the compiler works (especially with
     whatever libraries are installed) after building.


File: g77.info,  Node: Internals Documentation,  Next: Internals Improvements,  Prev: Machine Model,  Up: Projects

20.6 Internals Documentation
============================

Better info on how `g77' works and how to port it is needed.

   *Note Front End::, which contains some information on `g77'
internals.


File: g77.info,  Node: Internals Improvements,  Next: Better Diagnostics,  Prev: Internals Documentation,  Up: Projects

20.7 Internals Improvements
===========================

Some more items that would make `g77' more reliable and easier to
maintain:

   * Generally make expression handling focus more on critical syntax
     stuff, leaving semantics to callers.  For example, anything a
     caller can check, semantically, let it do so, rather than having
     `expr.c' do it.  (Exceptions might include things like diagnosing
     `FOO(I--K:)=BAR' where `FOO' is a `PARAMETER'--if it seems
     important to preserve the left-to-right-in-source order of
     production of diagnostics.)

   * Come up with better naming conventions for `-D' to establish
     requirements to achieve desired implementation dialect via
     `proj.h'.

   * Clean up used tokens and `ffewhere's in `ffeglobal_terminate_1'.

   * Replace `sta.c' `outpooldisp' mechanism with `malloc_pool_use'.

   * Check for `opANY' in more places in `com.c', `std.c', and `ste.c',
     and get rid of the `opCONVERT(opANY)' kludge (after determining if
     there is indeed no real need for it).

   * Utility to read and check `bad.def' messages and their references
     in the code, to make sure calls are consistent with message
     templates.

   * Search and fix `&ffe...' and similar so that `ffe...ptr...' macros
     are available instead (a good argument for wishing this could have
     written all this stuff in C++, perhaps).  On the other hand, it's
     questionable whether this sort of improvement is really necessary,
     given the availability of tools such as Emacs and Perl, which make
     finding any address-taking of structure members easy enough?

   * Some modules truly export the member names of their structures
     (and the structures themselves), maybe fix this, and fix other
     modules that just appear to as well (by appending `_', though it'd
     be ugly and probably not worth the time).

   * Implement C macros `RETURNS(value)' and `SETS(something,value)' in
     `proj.h' and use them throughout `g77' source code (especially in
     the definitions of access macros in `.h' files) so they can be
     tailored to catch code writing into a `RETURNS()' or reading from
     a `SETS()'.

   * Decorate throughout with `const' and other such stuff.

   * All F90 notational derivations in the source code are still based
     on the S8.112 version of the draft standard.  Probably should
     update to the official standard, or put documentation of the rules
     as used in the code...uh...in the code.

   * Some `ffebld_new' calls (those outside of `ffeexpr.c' or inside
     but invoked via paths not involving `ffeexpr_lhs' or
     `ffeexpr_rhs') might be creating things in improper pools, leading
     to such things staying around too long or (doubtful, but possible
     and dangerous) not long enough.

   * Some `ffebld_list_new' (or whatever) calls might not be matched by
     `ffebld_list_bottom' (or whatever) calls, which might someday
     matter.  (It definitely is not a problem just yet.)

   * Probably not doing clean things when we fail to `EQUIVALENCE'
     something due to alignment/mismatch or other problems--they end up
     without `ffestorag' objects, so maybe the backend (and other parts
     of the front end) can notice that and handle like an `opANY' (do
     what it wants, just don't complain or crash).  Most of this seems
     to have been addressed by now, but a code review wouldn't hurt.


File: g77.info,  Node: Better Diagnostics,  Prev: Internals Improvements,  Up: Projects

20.8 Better Diagnostics
=======================

These are things users might not ask about, or that need to be looked
into, before worrying about.  Also here are items that involve reducing
unnecessary diagnostic clutter.

   * When `FUNCTION' and `ENTRY' point types disagree (`CHARACTER'
     lengths, type classes, and so on), `ANY'-ize the offending `ENTRY'
     point and any _new_ dummies it specifies.

   * Speed up and improve error handling for data when repeat-count is
     specified.  For example, don't output 20 unnecessary messages
     after the first necessary one for:

          INTEGER X(20)
          CONTINUE
          DATA (X(I), J= 1, 20) /20*5/
          END

     (The `CONTINUE' statement ensures the `DATA' statement is
     processed in the context of executable, not specification,
     statements.)


File: g77.info,  Node: Front End,  Next: Diagnostics,  Prev: Projects,  Up: Top

21 Front End
************

This chapter describes some aspects of the design and implementation of
the `g77' front end.

   To find about things that are "To Be Determined" or "To Be Done",
search for the string TBD.  If you want to help by working on one or
more of these items, email <gcc@gcc.gnu.org>.  If you're planning to do
more than just research issues and offer comments, see
`http://gcc.gnu.org/contribute.html' for steps you might need to take
first.

* Menu:

* Overview of Sources::
* Overview of Translation Process::
* Philosophy of Code Generation::
* Two-pass Design::
* Challenges Posed::
* Transforming Statements::
* Transforming Expressions::
* Internal Naming Conventions::


File: g77.info,  Node: Overview of Sources,  Next: Overview of Translation Process,  Up: Front End

21.1 Overview of Sources
========================

The current directory layout includes the following:

`{No value for `srcdir'}/gcc/'
     Non-g77 files in gcc

`{No value for `srcdir'}/gcc/f/'
     GNU Fortran front end sources

`{No value for `srcdir'}/libf2c/'
     `libg2c' configuration and `g2c.h' file generation

`{No value for `srcdir'}/libf2c/libF77/'
     General support and math portion of `libg2c'

`{No value for `srcdir'}/libf2c/libI77/'
     I/O portion of `libg2c'

`{No value for `srcdir'}/libf2c/libU77/'
     Additional interfaces to Unix `libc' for `libg2c'

   Components of note in `g77' are described below.

   `f/' as a whole contains the source for `g77', while `libf2c/'
contains a portion of the separate program `f2c'.  Note that the
`libf2c' code is not part of the program `g77', just distributed with
it.

   `f/' contains text files that document the Fortran compiler, source
files for the GNU Fortran Front End (FFE), and some other stuff.  The
`g77' compiler code is placed in `f/' because it, along with its
contents, is designed to be a subdirectory of a `gcc' source directory,
`gcc/', which is structured so that language-specific front ends can be
"dropped in" as subdirectories.  The C++ front end (`g++'), is an
example of this--it resides in the `cp/' subdirectory.  Note that the C
front end (also referred to as `gcc') is an exception to this, as its
source files reside in the `gcc/' directory itself.

   `libf2c/' contains the run-time libraries for the `f2c' program,
also used by `g77'.  These libraries normally referred to collectively
as `libf2c'.  When built as part of `g77', `libf2c' is installed under
the name `libg2c' to avoid conflict with any existing version of
`libf2c', and thus is often referred to as `libg2c' when the `g77'
version is specifically being referred to.

   The `netlib' version of `libf2c/' contains two distinct libraries,
`libF77' and `libI77', each in their own subdirectories.  In `g77',
this distinction is not made, beyond maintaining the subdirectory
structure in the source-code tree.

   `libf2c/' is not part of the program `g77', just distributed with it.
It contains files not present in the official (`netlib') version of
`libf2c', and also contains some minor changes made from `libf2c', to
fix some bugs, and to facilitate automatic configuration, building, and
installation of `libf2c' (as `libg2c') for use by `g77' users.  See
`libf2c/README' for more information, including licensing conditions
governing distribution of programs containing code from `libg2c'.

   `libg2c', `g77''s version of `libf2c', adds Dave Love's
implementation of `libU77', in the `libf2c/libU77/' directory.  This
library is distributed under the GNU Library General Public License
(LGPL)--see the file `libf2c/libU77/COPYING.LIB' for more information,
as this license governs distribution conditions for programs containing
code from this portion of the library.

   Files of note in `f/' and `libf2c/' are described below:

`f/BUGS'
     Lists some important bugs known to be in g77.  Or use Info (or GNU
     Emacs Info mode) to read the "Actual Bugs" node of the `g77'
     documentation:

          info -f f/g77.info -n "Actual Bugs"

`f/ChangeLog'
     Lists recent changes to `g77' internals.

`libf2c/ChangeLog'
     Lists recent changes to `libg2c' internals.

`f/NEWS'
     Contains the per-release changes.  These include the user-visible
     changes described in the node "Changes" in the `g77'
     documentation, plus internal changes of import.  Or use:

          info -f f/g77.info -n News

`f/g77.info*'
     The `g77' documentation, in Info format, produced by building
     `g77'.

     All users of `g77' (not just installers) should read this, using
     the `more' command if neither the `info' command, nor GNU Emacs
     (with its Info mode), are available, or if users aren't yet
     accustomed to using these tools.  All of these files are readable
     as "plain text" files, though they're easier to navigate using
     Info readers such as `info' and GNU Emacs Info mode.

   If you want to explore the FFE code, which lives entirely in `f/',
here are a few clues.  The file `g77spec.c' contains the `g77'-specific
source code for the `g77' command only--this just forms a variant of the
`gcc' command, so, just as the `gcc' command itself does not contain
the C front end, the `g77' command does not contain the Fortran front
end (FFE).  The FFE code ends up in an executable named `f771', which
does the actual compiling, so it contains the FFE plus the `gcc' back
end (GBE), the latter to do most of the optimization, and the code
generation.

   The file `parse.c' is the source file for `yyparse()', which is
invoked by the GBE to start the compilation process, for `f771'.

   The file `top.c' contains the top-level FFE function `ffe_file' and
it (along with top.h) define all `ffe_[a-z].*', `ffe[A-Z].*', and
`FFE_[A-Za-z].*' symbols.

   The file `fini.c' is a `main()' program that is used when building
the FFE to generate C header and source files for recognizing keywords.
The files `malloc.c' and `malloc.h' comprise a memory manager that
defines all `malloc_[a-z].*', `malloc[A-Z].*', and `MALLOC_[A-Za-z].*'
symbols.

   All other modules named XYZ are comprised of all files named
`XYZ*.EXT' and define all `ffeXYZ_[a-z].*', `ffeXYZ[A-Z].*', and
`FFEXYZ_[A-Za-z].*' symbols.  If you understand all this,
congratulations--it's easier for me to remember how it works than to
type in these regular expressions.  But it does make it easy to find
where a symbol is defined.  For example, the symbol
`ffexyz_set_something' would be defined in `xyz.h' and implemented
there (if it's a macro) or in `xyz.c'.

   The "porting" files of note currently are:

`proj.c'
`proj.h'
     This defines the "language" used by all the other source files,
     the language being Standard C plus some useful things like
     `ARRAY_SIZE' and such.

`target.c'
`target.h'
     These describe the target machine in terms of what data types are
     supported, how they are denoted (to what C type does an
     `INTEGER*8' map, for example), how to convert between them, and so
     on.  Over time, versions of `g77' rely less on this file and more
     on run-time configuration based on GBE info in `com.c'.

`com.c'
`com.h'
     These are the primary interface to the GBE.

`ste.c'
`ste.h'
     This contains code for implementing recognized executable
     statements in the GBE.

`src.c'
`src.h'
     These contain information on the format(s) of source files (such
     as whether they are never to be processed as case-insensitive with
     regard to Fortran keywords).

   If you want to debug the `f771' executable, for example if it
crashes, note that the global variables `lineno' and `input_filename'
are usually set to reflect the current line being read by the lexer
during the first-pass analysis of a program unit and to reflect the
current line being processed during the second-pass compilation of a
program unit.

   If an invocation of the function `ffestd_exec_end' is on the stack,
the compiler is in the second pass, otherwise it is in the first.

   (This information might help you reduce a test case and/or work
around a bug in `g77' until a fix is available.)


File: g77.info,  Node: Overview of Translation Process,  Next: Philosophy of Code Generation,  Prev: Overview of Sources,  Up: Front End

21.2 Overview of Translation Process
====================================

The order of phases translating source code to the form accepted by the
GBE is:

  1. Stripping punched-card sources (`g77stripcard.c')

  2. Lexing (`lex.c')

  3. Stand-alone statement identification (`sta.c')

  4. INCLUDE handling (`sti.c')

  5. Order-dependent statement identification (`stq.c')

  6. Parsing (`stb.c' and `expr.c')

  7. Constructing (`stc.c')

  8. Collecting (`std.c')

  9. Expanding (`ste.c')

   To get a rough idea of how a particularly twisted Fortran statement
gets treated by the passes, consider:

           FORMAT(I2 4H)=(J/
          &   I3)

   The job of `lex.c' is to know enough about Fortran syntax rules to
break the statement up into distinct lexemes without requiring any
feedback from subsequent phases:

     `FORMAT'
     `('
     `I24H'
     `)'
     `='
     `('
     `J'
     `/'
     `I3'
     `)'

   The job of `sta.c' is to figure out the kind of statement, or, at
least, statement form, that sequence of lexemes represent.

   The sooner it can do this (in terms of using the smallest number of
lexemes, starting with the first for each statement), the better,
because that leaves diagnostics for problems beyond the recognition of
the statement form to subsequent phases, which can usually better
describe the nature of the problem.

   In this case, the `=' at "level zero" (not nested within parentheses)
tells `sta.c' that this is an _assignment-form_, not `FORMAT',
statement.

   An assignment-form statement might be a statement-function
definition or an executable assignment statement.

   To make that determination, `sta.c' looks at the first two lexemes.

   Since the second lexeme is `(', the first must represent an array
for this to be an assignment statement, else it's a statement function.

   Either way, `sta.c' hands off the statement to `stq.c' (via `sti.c',
which expands INCLUDE files).  `stq.c' figures out what a statement
that is, on its own, ambiguous, must actually be based on the context
established by previous statements.

   So, `stq.c' watches the statement stream for executable statements,
END statements, and so on, so it knows whether `A(B)=C' is (intended
as) a statement-function definition or an assignment statement.

   After establishing the context-aware statement info, `stq.c' passes
the original sample statement on to `stb.c' (either its
statement-function parser or its assignment-statement parser).

   `stb.c' forms a statement-specific record containing the pertinent
information.  That information includes a source expression and, for an
assignment statement, a destination expression.  Expressions are parsed
by `expr.c'.

   This record is passed to `stc.c', which copes with the implications
of the statement within the context established by previous statements.

   For example, if it's the first statement in the file or after an
`END' statement, `stc.c' recognizes that, first of all, a main program
unit is now being lexed (and tells that to `std.c' before telling it
about the current statement).

   `stc.c' attaches whatever information it can, usually derived from
the context established by the preceding statements, and passes the
information to `std.c'.

   `std.c' saves this information away, since the GBE cannot cope with
information that might be incomplete at this stage.

   For example, `I3' might later be determined to be an argument to an
alternate `ENTRY' point.

   When `std.c' is told about the end of an external (top-level)
program unit, it passes all the information it has saved away on
statements in that program unit to `ste.c'.

   `ste.c' "expands" each statement, in sequence, by constructing the
appropriate GBE information and calling the appropriate GBE routines.

   Details on the transformational phases follow.  Keep in mind that
Fortran numbering is used, so the first character on a line is column 1,
decimal numbering is used, and so on.

* Menu:

* g77stripcard::
* lex.c::
* sta.c::
* sti.c::
* stq.c::
* stb.c::
* expr.c::
* stc.c::
* std.c::
* ste.c::

* Gotchas (Transforming)::
* TBD (Transforming)::


File: g77.info,  Node: g77stripcard,  Next: lex.c,  Up: Overview of Translation Process

21.2.1 g77stripcard
-------------------

The `g77stripcard' program handles removing content beyond column 72
(adjustable via a command-line option), optionally warning about that
content being something other than trailing whitespace or Fortran
commentary.

   This program is needed because `lex.c' doesn't pay attention to
maximum line lengths at all, to make it easier to maintain, as well as
faster (for sources that don't depend on the maximum column length
vis-a-vis trailing non-blank non-commentary content).

   Just how this program will be run--whether automatically for old
source (perhaps as the default for `.f' files?)--is not yet determined.

   In the meantime, it might as well be implemented as a typical UNIX
pipe.

   It should accept a `-fline-length-N' option, with the default line
length set to 72.

   When the text it strips off the end of a line is not blank (not
spaces and tabs), it should insert an additional comment line
(beginning with `!', so it works for both fixed-form and free-form
files) containing the text, following the stripped line.  The inserted
comment should have a prefix of some kind, TBD, that distinguishes the
comment as representing stripped text.  Users could use that to `sed'
out such lines, if they wished--it seems silly to provide a
command-line option to delete information when it can be so easily
filtered out by another program.

   (This inserted comment should be designed to "fit in" well with
whatever the Fortran community is using these days for preprocessor,
translator, and other such products, like OpenMP.  What that's all
about, and how `g77' can elegantly fit its special comment conventions
into it all, is TBD as well.  We don't want to reinvent the wheel here,
but if there turn out to be too many conflicting conventions, we might
have to invent one that looks nothing like the others, but which offers
their host products a better infrastructure in which to fit and coexist
peacefully.)

   `g77stripcard' probably shouldn't do any tab expansion or other
fancy stuff.  People can use `expand' or other pre-filtering if they
like.  The idea here is to keep each stage quite simple, while providing
excellent performance for "normal" code.

   (Code with junk beyond column 73 is not really "normal", as it comes
from a card-punch heritage, and will be increasingly hard for
tomorrow's Fortran programmers to read.)


File: g77.info,  Node: lex.c,  Next: sta.c,  Prev: g77stripcard,  Up: Overview of Translation Process

21.2.2 lex.c
------------

To help make the lexer simple, fast, and easy to maintain, while also
having `g77' generally encourage Fortran programmers to write simple,
maintainable, portable code by maximizing the performance of compiling
that kind of code:

   * There'll be just one lexer, for both fixed-form and free-form
     source.

   * It'll care about the form only when handling the first 7 columns of
     text, stuff like spaces between strings of alphanumerics, and how
     lines are continued.

     Some other distinctions will be handled by subsequent phases, so
     at least one of them will have to know which form is involved.

     For example, `I = 2 . 4' is acceptable in fixed form, and works in
     free form as well given the implementation `g77' presently uses.
     But the standard requires a diagnostic for it in free form, so the
     parser has to be able to recognize that the lexemes aren't
     contiguous (information the lexer _does_ have to provide) and that
     free-form source is being parsed, so it can provide the diagnostic.

     The `g77' lexer doesn't try to gather `2 . 4' into a single lexeme.
     Otherwise, it'd have to know a whole lot more about how to parse
     Fortran, or subsequent phases (mainly parsing) would have two
     paths through lots of critical code--one to handle the lexeme `2',
     `.', and `4' in sequence, another to handle the lexeme `2.4'.

   * It won't worry about line lengths (beyond the first 7 columns for
     fixed-form source).

     That is, once it starts parsing the "statement" part of a line
     (column 7 for fixed-form, column 1 for free-form), it'll keep
     going until it finds a newline, rather than ignoring everything
     past a particular column (72 or 132).

     The implication here is that there shouldn't _be_ anything past
     that last column, other than whitespace or commentary, because
     users using typical editors (or viewing output as typically
     printed) won't necessarily know just where the last column is.

     Code that has "garbage" beyond the last column (almost certainly
     only fixed-form code with a punched-card legacy, such as code
     using columns 73-80 for "sequence numbers") will have to be run
     through `g77stripcard' first.

     Also, keeping track of the maximum column position while also
     watching out for the end of a line _and_ while reading from a file
     just makes things slower.  Since a file must be read, and watching
     for the end of the line is necessary (unless the typical input
     file was preprocessed to include the necessary number of trailing
     spaces), dropping the tracking of the maximum column position is
     the only way to reduce the complexity of the pertinent code while
     maintaining high performance.

   * ASCII encoding is assumed for the input file.

     Code written in other character sets will have to be converted
     first.

   * Tabs (ASCII code 9) will be converted to spaces via the
     straightforward approach.

     Specifically, a tab is converted to between one and eight spaces
     as necessary to reach column N, where dividing `(N - 1)' by eight
     results in a remainder of zero.

     That saves having to pass most source files through `expand'.

   * Linefeeds (ASCII code 10) mark the ends of lines.

   * A carriage return (ASCII code 13) is accept if it immediately
     precedes a linefeed, in which case it is ignored.

     Otherwise, it is rejected (with a diagnostic).

   * Any other characters other than the above that are not part of the
     GNU Fortran Character Set (*note Character Set::) are rejected
     with a diagnostic.

     This includes backspaces, form feeds, and the like.

     (It might make sense to allow a form feed in column 1 as long as
     that's the only character on a line.  It certainly wouldn't seem
     to cost much in terms of performance.)

   * The end of the input stream (EOF) ends the current line.

   * The distinction between uppercase and lowercase letters will be
     preserved.

     It will be up to subsequent phases to decide to fold case.

     Current plans are to permit any casing for Fortran (reserved)
     keywords while preserving casing for user-defined names.  (This
     might not be made the default for `.f' files, though.)

     Preserving case seems necessary to provide more direct access to
     facilities outside of `g77', such as to C or Pascal code.

     Names of intrinsics will probably be matchable in any case,

     (How `external SiN; r = sin(x)' would be handled is TBD.  I think
     old `g77' might already handle that pretty elegantly, but whether
     we can cope with allowing the same fragment to reference a
     _different_ procedure, even with the same interface, via `s =
     SiN(r)', needs to be determined.  If it can't, we need to make
     sure that when code introduces a user-defined name, any intrinsic
     matching that name using a case-insensitive comparison is "turned
     off".)

   * Backslashes in `CHARACTER' and Hollerith constants are not allowed.

     This avoids the confusion introduced by some Fortran compiler
     vendors providing C-like interpretation of backslashes, while
     others provide straight-through interpretation.

     Some kind of lexical construct (TBD) will be provided to allow
     flagging of a `CHARACTER' (but probably not a Hollerith) constant
     that permits backslashes.  It'll necessarily be a prefix, such as:

          PRINT *, C'This line has a backspace \b here.'
          PRINT *, F'This line has a straight backslash \ here.'

     Further, command-line options might be provided to specify that
     one prefix or the other is to be assumed as the default for
     `CHARACTER' constants.

     However, it seems more helpful for `g77' to provide a program that
     converts prefix all constants (or just those containing
     backslashes) with the desired designation, so printouts of code
     can be read without knowing the compile-time options used when
     compiling it.

     If such a program is provided (let's name it `g77slash' for now),
     then a command-line option to `g77' should not be provided.
     (Though, given that it'll be easy to implement, it might be hard
     to resist user requests for it "to compile faster than if we have
     to invoke another filter".)

     This program would take a command-line option to specify the
     default interpretation of slashes, affecting which prefix it uses
     for constants.

     `g77slash' probably should automatically convert Hollerith
     constants that contain slashes to the appropriate `CHARACTER'
     constants.  Then `g77' wouldn't have to define a prefix syntax for
     Hollerith constants specifying whether they want C-style or
     straight-through backslashes.

   * To allow for form-neutral INCLUDE files without requiring them to
     be preprocessed, the fixed-form lexer should offer an extension
     (if possible) allowing a trailing `&' to be ignored, especially if
     after column 72, as it would be using the traditional Unix Fortran
     source model (which ignores _everything_ after column 72).

   The above implements nearly exactly what is specified by *Note
Character Set::, and *Note Lines::, except it also provides automatic
conversion of tabs and ignoring of newline-related carriage returns, as
well as accommodating form-neutral INCLUDE files.

   It also implements the "pure visual" model, by which is meant that a
user viewing his code in a typical text editor (assuming it's not
preprocessed via `g77stripcard' or similar) doesn't need any special
knowledge of whether spaces on the screen are really tabs, whether
lines end immediately after the last visible non-space character or
after a number of spaces and tabs that follow it, or whether the last
line in the file is ended by a newline.

   Most editors don't make these distinctions, the ANSI FORTRAN 77
standard doesn't require them to, and it permits a standard-conforming
compiler to define a method for transforming source code to "standard
form" however it wants.

   So, GNU Fortran defines it such that users have the best chance of
having the code be interpreted the way it looks on the screen of the
typical editor.

   (Fancy editors should _never_ be required to correctly read code
written in classic two-dimensional-plaintext form.  By correct reading
I mean ability to read it, book-like, without mistaking text ignored by
the compiler for program code and vice versa, and without having to
count beyond the first several columns.  The vague meaning of ASCII
TAB, among other things, complicates this somewhat, but as long as
"everyone", including the editor, other tools, and printer, agrees
about the every-eighth-column convention, the GNU Fortran "pure visual"
model meets these requirements.  Any language or user-visible source
form requiring special tagging of tabs, the ends of lines after
spaces/tabs, and so on, fails to meet this fairly straightforward
specification.  Fortunately, Fortran _itself_ does not mandate such a
failure, though most vendor-supplied defaults for their Fortran
compilers _do_ fail to meet this specification for readability.)

   Further, this model provides a clean interface to whatever
preprocessors or code-generators are used to produce input to this
phase of `g77'.  Mainly, they need not worry about long lines.


File: g77.info,  Node: sta.c,  Next: sti.c,  Prev: lex.c,  Up: Overview of Translation Process

21.2.3 sta.c
------------


File: g77.info,  Node: sti.c,  Next: stq.c,  Prev: sta.c,  Up: Overview of Translation Process

21.2.4 sti.c
------------


File: g77.info,  Node: stq.c,  Next: stb.c,  Prev: sti.c,  Up: Overview of Translation Process

21.2.5 stq.c
------------


File: g77.info,  Node: stb.c,  Next: expr.c,  Prev: stq.c,  Up: Overview of Translation Process

21.2.6 stb.c
------------


File: g77.info,  Node: expr.c,  Next: stc.c,  Prev: stb.c,  Up: Overview of Translation Process

21.2.7 expr.c
-------------


File: g77.info,  Node: stc.c,  Next: std.c,  Prev: expr.c,  Up: Overview of Translation Process

21.2.8 stc.c
------------


File: g77.info,  Node: std.c,  Next: ste.c,  Prev: stc.c,  Up: Overview of Translation Process

21.2.9 std.c
------------


File: g77.info,  Node: ste.c,  Next: Gotchas (Transforming),  Prev: std.c,  Up: Overview of Translation Process

21.2.10 ste.c
-------------


File: g77.info,  Node: Gotchas (Transforming),  Next: TBD (Transforming),  Prev: ste.c,  Up: Overview of Translation Process

21.2.11 Gotchas (Transforming)
------------------------------

This section is not about transforming "gotchas" into something else.
It is about the weirder aspects of transforming Fortran, however that's
defined, into a more modern, canonical form.

21.2.11.1 Multi-character Lexemes
.................................

Each lexeme carries with it a pointer to where it appears in the source.

   To provide the ability for diagnostics to point to column numbers,
in addition to line numbers and names, lexemes that represent more than
one (significant) character in the source code need, generally, to
provide pointers to where each _character_ appears in the source.

   This provides the ability to properly identify the precise location
of the problem in code like

     SUBROUTINE X
     END
     BLOCK DATA X
     END

   which, in fixed-form source, would result in single lexemes
consisting of the strings `SUBROUTINEX' and `BLOCKDATAX'.  (The problem
is that `X' is defined twice, so a pointer to the `X' in the second
definition, as well as a follow-up pointer to the corresponding pointer
in the first, would be preferable to pointing to the beginnings of the
statements.)

   This need also arises when parsing (and diagnosing) `FORMAT'
statements.

   Further, it arises when diagnosing `FMT=' specifiers that contain
constants (or partial constants, or even propagated constants!)  in I/O
statements, as in:

     PRINT '(I2, 3HAB)', J

   (A pointer to the beginning of the prematurely-terminated Hollerith
constant, and/or to the close parenthese, is preferable to a pointer to
the open-parenthese or the apostrophe that precedes it.)

   Multi-character lexemes, which would seem to naturally include at
least digit strings, alphanumeric strings, `CHARACTER' constants, and
Hollerith constants, therefore need to provide location information on
each character.  (Maybe Hollerith constants don't, but it's unnecessary
to except them.)

   The question then arises, what about _other_ multi-character lexemes,
such as `**' and `//', and Fortran 90's `(/', `/)', `::', and so on?

   Turns out there's a need to identify the location of the second
character of these two-character lexemes.  For example, in `I(/J) = K',
the slash needs to be diagnosed as the problem, not the open parenthese.
Similarly, it is preferable to diagnose the second slash in `I = J //
K' rather than the first, given the implicit typing rules, which would
result in the compiler disallowing the attempted concatenation of two
integers.  (Though, since that's more of a semantic issue, it's not
_that_ much preferable.)

   Even sequences that could be parsed as digit strings could use
location info, for example, to diagnose the `9' in the octal constant
`O'129''.  (This probably will be parsed as a character string, to be
consistent with the parsing of `Z'129A''.)

   To avoid the hassle of recording the location of the second
character, while also preserving the general rule that each significant
character is distinctly pointed to by the lexeme that contains it, it's
best to simply not have any fixed-size lexemes larger than one
character.

   This new design is expected to make checking for two `*' lexemes in
a row much easier than the old design, so this is not much of a
sacrifice.  It probably makes the lexer much easier to implement than
it makes the parser harder.

21.2.11.2 Space-padding Lexemes
...............................

Certain lexemes need to be padded with virtual spaces when the end of
the line (or file) is encountered.

   This is necessary in fixed form, to handle lines that don't extend
to column 72, assuming that's the line length in effect.

21.2.11.3 Bizarre Free-form Hollerith Constants
...............................................

Last I checked, the Fortran 90 standard actually required the compiler
to silently accept something like

     FORMAT ( 1 2   Htwelve chars )

   as a valid `FORMAT' statement specifying a twelve-character
Hollerith constant.

   The implication here is that, since the new lexer is a zero-feedback
one, it won't know that the special case of a `FORMAT' statement being
parsed requires apparently distinct lexemes `1' and `2' to be treated as
a single lexeme.

   (This is a horrible misfeature of the Fortran 90 language.  It's one
of many such misfeatures that almost make me want to not support them,
and forge ahead with designing a new "GNU Fortran" language that has
the features, but not the misfeatures, of Fortran 90, and provide
utility programs to do the conversion automatically.)

   So, the lexer must gather distinct chunks of decimal strings into a
single lexeme in contexts where a single decimal lexeme might start a
Hollerith constant.

   (Which probably means it might as well do that all the time for all
multi-character lexemes, even in free-form mode, leaving it to
subsequent phases to pull them apart as they see fit.)

   Compare the treatment of this to how

     CHARACTER * 4 5 HEY

   and

     CHARACTER * 12 HEY

   must be treated--the former must be diagnosed, due to the separation
between lexemes, the latter must be accepted as a proper declaration.

21.2.11.4 Hollerith Constants
.............................

Recognizing a Hollerith constant--specifically, that an `H' or `h'
after a digit string begins such a constant--requires some knowledge of
context.

   Hollerith constants (such as `2HAB') can appear after:

   * `('

   * `,'

   * `='

   * `+', `-', `/'

   * `*', except as noted below

   Hollerith constants don't appear after:

   * `CHARACTER*', which can be treated generally as any `*' that is
     the second lexeme of a statement

21.2.11.5 Confusing Function Keyword
....................................

While

     REAL FUNCTION FOO ()

   must be a `FUNCTION' statement and

     REAL FUNCTION FOO (5)

   must be a type-definition statement,

     REAL FUNCTION FOO (NAMES)

   where NAMES is a comma-separated list of names, can be one or the
other.

   The only way to disambiguate that statement (short of mandating
free-form source or a short maximum length for name for external
procedures) is based on the context of the statement.

   In particular, the statement is known to be within an
already-started program unit (but not at the outer level of the
`CONTAINS' block), it is a type-declaration statement.

   Otherwise, the statement is a `FUNCTION' statement, in that it
begins a function program unit (external, or, within `CONTAINS',
nested).

21.2.11.6 Weird READ
....................

The statement

     READ (N)

   is equivalent to either

     READ (UNIT=(N))

   or

     READ (FMT=(N))

   depending on which would be valid in context.

   Specifically, if `N' is type `INTEGER', `READ (FMT=(N))' would not
be valid, because parentheses may not be used around `N', whereas they
may around it in `READ (UNIT=(N))'.

   Further, if `N' is type `CHARACTER', the opposite is true--`READ
(UNIT=(N))' is not valid, but `READ (FMT=(N))' is.

   Strictly speaking, if anything follows

     READ (N)

   in the statement, whether the first lexeme after the close
parenthese is a comma could be used to disambiguate the two cases,
without looking at the type of `N', because the comma is required for
the `READ (FMT=(N))' interpretation and disallowed for the `READ
(UNIT=(N))' interpretation.

   However, in practice, many Fortran compilers allow the comma for the
`READ (UNIT=(N))' interpretation anyway (in that they generally allow a
leading comma before an I/O list in an I/O statement), and much code
takes advantage of this allowance.

   (This is quite a reasonable allowance, since the juxtaposition of a
comma-separated list immediately after an I/O control-specification
list, which is also comma-separated, without an intervening comma,
looks sufficiently "wrong" to programmers that they can't resist the
itch to insert the comma.  `READ (I, J), K, L' simply looks cleaner than
`READ (I, J) K, L'.)

   So, type-based disambiguation is needed unless strict adherence to
the standard is always assumed, and we're not going to assume that.


File: g77.info,  Node: TBD (Transforming),  Prev: Gotchas (Transforming),  Up: Overview of Translation Process

21.2.12 TBD (Transforming)
--------------------------

Continue researching gotchas, designing the transformational process,
and implementing it.

   Specific issues to resolve:

   * Just where should (if it was implemented) `USE' processing take
     place?

     This gets into the whole issue of how `g77' should handle the
     concept of modules.  I think GNAT already takes on this issue, but
     don't know more than that.  Jim Giles has written extensively on
     `comp.lang.fortran' about his opinions on module handling, as have
     others.  Jim's views should be taken into account.

     Actually, Richard M. Stallman (RMS) also has written up some
     guidelines for implementing such things, but I'm not sure where I
     read them.  Perhaps the old <gcc2@cygnus.com> list.

     If someone could dig references to these up and get them to me,
     that would be much appreciated!  Even though modules are not on
     the short-term list for implementation, it'd be helpful to know
     _now_ how to avoid making them harder to implement them _later_.

   * Should the `g77' command become just a script that invokes all the
     various preprocessing that might be needed, thus making it seem
     slower than necessary for legacy code that people are unwilling to
     convert, or should we provide a separate script for that, thus
     encouraging people to convert their code once and for all?

     At least, a separate script to behave as old `g77' did, perhaps
     named `g77old', might ease the transition, as might a
     corresponding one that converts source codes named `g77oldnew'.

     These scripts would take all the pertinent options `g77' used to
     take and run the appropriate filters, passing the results to `g77'
     or just making new sources out of them (in a subdirectory, leaving
     the user to do the dirty deed of moving or copying them over the
     old sources).

   * Do other Fortran compilers provide a prefix syntax to govern the
     treatment of backslashes in `CHARACTER' (or Hollerith) constants?

     Knowing what other compilers provide would help.

   * Is it okay to drop support for the `-fintrin-case-initcap',
     `-fmatch-case-initcap', `-fsymbol-case-initcap', and
     `-fcase-initcap' options?

     I've asked <info-gnu-fortran@gnu.org> for input on this.  Not
     having to support these makes it easier to write the new front end,
     and might also avoid complicated its design.

     The consensus to date (1999-11-17) has been to drop this support.
     Can't recall anybody saying they're using it, in fact.


File: g77.info,  Node: Philosophy of Code Generation,  Next: Two-pass Design,  Prev: Overview of Translation Process,  Up: Front End

21.3 Philosophy of Code Generation
==================================

Don't poke the bear.

   The `g77' front end generates code via the `gcc' back end.

   The `gcc' back end (GBE) is a large, complex labyrinth of intricate
code written in a combination of the C language and specialized
languages internal to `gcc'.

   While the _code_ that implements the GBE is written in a combination
of languages, the GBE itself is, to the front end for a language like
Fortran, best viewed as a _compiler_ that compiles its own, unique,
language.

   The GBE's "source", then, is written in this language, which
consists primarily of a combination of calls to GBE functions and
"tree" nodes (which are, themselves, created by calling GBE functions).

   So, the `g77' generates code by, in effect, translating the Fortran
code it reads into a form "written" in the "language" of the `gcc' back
end.

   This language will heretofore be referred to as "GBEL", for GNU Back
End Language.

   GBEL is an evolving language, not fully specified in any published
form as of this writing.  It offers many facilities, but its "core"
facilities are those that corresponding most directly to those needed
to support `gcc' (compiling code written in GNU C).

   The `g77' Fortran Front End (FFE) is designed and implemented to
navigate the currents and eddies of ongoing GBEL and `gcc' development
while also delivering on the potential of an integrated FFE (as
compared to using a converter like `f2c' and feeding the output into
`gcc').

   Goals of the FFE's code-generation strategy include:

   * High likelihood of generation of correct code, or, failing that,
     producing a fatal diagnostic or crashing.

   * Generation of highly optimized code, as directed by the user via
     GBE-specific (versus `g77'-specific) constructs, such as
     command-line options.

   * Fast overall (FFE plus GBE) compilation.

   * Preservation of source-level debugging information.

   The strategies historically, and currently, used by the FFE to
achieve these goals include:

   * Use of GBEL constructs that most faithfully encapsulate the
     semantics of Fortran.

   * Avoidance of GBEL constructs that are so rarely used, or limited
     to use in specialized situations not related to Fortran, that
     their reliability and performance has not yet been established as
     sufficient for use by the FFE.

   * Flexible design, to readily accommodate changes to specific
     code-generation strategies, perhaps governed by command-line
     options.

   "Don't poke the bear" somewhat summarizes the above strategies.  The
GBE is the bear.  The FFE is designed and implemented to avoid poking it
in ways that are likely to just annoy it.  The FFE usually either
tackles it head-on, or avoids treating it in ways dissimilar to how the
`gcc' front end treats it.

   For example, the FFE uses the native array facility in the back end
instead of the lower-level pointer-arithmetic facility used by `gcc'
when compiling `f2c' output).  Theoretically, this presents more
opportunities for optimization, faster compile times, and the
production of more faithful debugging information.  These benefits were
not, however, immediately realized, mainly because `gcc' itself makes
little or no use of the native array facility.

   Complex arithmetic is a case study of the evolution of this strategy.
When originally implemented, the GBEL had just evolved its own native
complex-arithmetic facility, so the FFE took advantage of that.

   When porting `g77' to 64-bit systems, it was discovered that the GBE
didn't really implement its native complex-arithmetic facility properly.

   The short-term solution was to rewrite the FFE to instead use the
lower-level facilities that'd be used by `gcc'-compiled code (assuming
that code, itself, didn't use the native complex type provided, as an
extension, by `gcc'), since these were known to work, and, in any case,
if shown to not work, would likely be rapidly fixed (since they'd
likely not work for vanilla C code in similar circumstances).

   However, the rewrite accommodated the original, native approach as
well by offering a command-line option to select it over the emulated
approach.  This allowed users, and especially GBE maintainers, to try
out fixes to complex-arithmetic support in the GBE while `g77'
continued to default to compiling more code correctly, albeit producing
(typically) slower executables.

   As of April 1999, it appeared that the last few bugs in the GBE's
support of its native complex-arithmetic facility were worked out.  The
FFE was changed back to default to using that native facility, leaving
emulation as an option.

   Later during the release cycle (which was called EGCS 1.2, but soon
became GCC 2.95), bugs in the native facility were found.  Reactions
among various people included "the last thing we should do is change
the default back", "we must change the default back", and "let's figure
out whether we can narrow down the bugs to few enough cases to allow
the now-months-long-tested default to remain the same".  The latter
viewpoint won that particular time.  The bugs exposed other concerns
regarding ABI compliance when the ABI specified treatment of complex
data as different from treatment of what Fortran and GNU C consider the
equivalent aggregation (structure) of real (or float) pairs.

   Other Fortran constructs--arrays, character strings, complex
division, `COMMON' and `EQUIVALENCE' aggregates, and so on--involve
issues similar to those pertaining to complex arithmetic.

   So, it is possible that the history of how the FFE handled complex
arithmetic will be repeated, probably in modified form (and hopefully
over shorter timeframes), for some of these other facilities.


File: g77.info,  Node: Two-pass Design,  Next: Challenges Posed,  Prev: Philosophy of Code Generation,  Up: Front End

21.4 Two-pass Design
====================

The FFE does not tell the GBE anything about a program unit until after
the last statement in that unit has been parsed.  (A program unit is a
Fortran concept that corresponds, in the C world, mostly closely to
functions definitions in ISO C.  That is, a program unit in Fortran is
like a top-level function in C.  Nested functions, found among the
extensions offered by GNU C, correspond roughly to Fortran's statement
functions.)

   So, while parsing the code in a program unit, the FFE saves up all
the information on statements, expressions, names, and so on, until it
has seen the last statement.

   At that point, the FFE revisits the saved information (in what
amounts to a second "pass" over the program unit) to perform the actual
translation of the program unit into GBEL, ultimating in the generation
of assembly code for it.

   Some lookahead is performed during this second pass, so the FFE
could be viewed as a "two-plus-pass" design.

* Menu:

* Two-pass Code::
* Why Two Passes::


File: g77.info,  Node: Two-pass Code,  Next: Why Two Passes,  Up: Two-pass Design

21.4.1 Two-pass Code
--------------------

Most of the code that turns the first pass (parsing) into a second pass
for code generation is in `gcc/gcc/f/std.c'.

   It has external functions, called mainly by siblings in
`gcc/gcc/f/stc.c', that record the information on statements and
expressions in the order they are seen in the source code.  These
functions save that information.

   It also has an external function that revisits that information,
calling the siblings in `gcc/gcc/f/ste.c', which handles the actual
code generation (by generating GBEL code, that is, by calling GBE
routines to represent and specify expressions, statements, and so on).


File: g77.info,  Node: Why Two Passes,  Prev: Two-pass Code,  Up: Two-pass Design

21.4.2 Why Two Passes
---------------------

The need for two passes was not immediately evident during the design
and implementation of the code in the FFE that was to produce GBEL.
Only after a few kludges, to handle things like incorrectly-guessed
`ASSIGN' label nature, had been implemented, did enough evidence pile
up to make it clear that `std.c' had to be introduced to intercept,
save, then revisit as part of a second pass, the digested contents of a
program unit.

   Other such missteps have occurred during the evolution of the FFE,
because of the different goals of the FFE and the GBE.

   Because the GBE's original, and still primary, goal was to directly
support the GNU C language, the GBEL, and the GBE itself, requires more
complexity on the part of most front ends than it requires of `gcc''s.

   For example, the GBEL offers an interface that permits the `gcc'
front end to implement most, or all, of the language features it
supports, without the front end having to make use of non-user-defined
variables.  (It's almost certainly the case that all of K&R C, and
probably ANSI C as well, is handled by the `gcc' front end without
declaring such variables.)

   The FFE, on the other hand, must resort to a variety of "tricks" to
achieve its goals.

   Consider the following C code:

     int
     foo (int a, int b)
     {
       int c = 0;

       if ((c = bar (c)) == 0)
         goto done;

       quux (c << 1);

     done:
       return c;
     }

   Note what kinds of objects are declared, or defined, before their
use, and before any actual code generation involving them would
normally take place:

   * Return type of function

   * Entry point(s) of function

   * Dummy arguments

   * Variables

   * Initial values for variables

   Whereas, the following items can, and do, suddenly appear "out of
the blue" in C:

   * Label references

   * Function references

   Not surprisingly, the GBE faithfully permits the latter set of items
to be "discovered" partway through GBEL "programs", just as they are
permitted to in C.

   Yet, the GBE has tended, at least in the past, to be reticent to
fully support similar "late" discovery of items in the former set.

   This makes Fortran a poor fit for the "safe" subset of GBEL.
Consider:

           FUNCTION X (A, ARRAY, ID1)
           CHARACTER*(*) A
           DOUBLE PRECISION X, Y, Z, TMP, EE, PI
           REAL ARRAY(ID1*ID2)
           COMMON ID2
           EXTERNAL FRED

           ASSIGN 100 TO J
           CALL FOO (I)
           IF (I .EQ. 0) PRINT *, A(0)
           GOTO 200

           ENTRY Y (Z)
           ASSIGN 101 TO J
     200   PRINT *, A(1)
           READ *, TMP
           GOTO J
     100   X = TMP * EE
           RETURN
     101   Y = TMP * PI
           CALL FRED
           DATA EE, PI /2.71D0, 3.14D0/
           END

   Here are some observations about the above code, which, while
somewhat contrived, conforms to the FORTRAN 77 and Fortran 90 standards:

   * The return type of function `X' is not known until the `DOUBLE
     PRECISION' line has been parsed.

   * Whether `A' is a function or a variable is not known until the
     `PRINT *, A(0)' statement has been parsed.

   * The bounds of the array of argument `ARRAY' depend on a
     computation involving the subsequent argument `ID1' and the
     blank-common member `ID2'.

   * Whether `Y' and `Z' are local variables, additional function entry
     points, or dummy arguments to additional entry points is not known
     until the `ENTRY' statement is parsed.

   * Similarly, whether `TMP' is a local variable is not known until
     the `READ *, TMP' statement is parsed.

   * The initial values for `EE' and `PI' are not known until after the
     `DATA' statement is parsed.

   * Whether `FRED' is a function returning type `REAL' or a subroutine
     (which can be thought of as returning type `void' _or_, to support
     alternate returns in a simple way, type `int') is not known until
     the `CALL FRED' statement is parsed.

   * Whether `100' is a `FORMAT' label or the label of an executable
     statement is not known until the `X =' statement is parsed.
     (These two types of labels get _very_ different treatment,
     especially when `ASSIGN''ed.)

   * That `J' is a local variable is not known until the first `ASSIGN'
     statement is parsed.  (This happens _after_ executable code has
     been seen.)

   Very few of these "discoveries" can be accommodated by the GBE as it
has evolved over the years.  The GBEL doesn't support several of them,
and those it might appear to support don't always work properly,
especially in combination with other GBEL and GBE features, as
implemented in the GBE.

   (Had the GBE and its GBEL originally evolved to support `g77', the
shoe would be on the other foot, so to speak--most, if not all, of the
above would be directly supported by the GBEL, and a few C constructs
would probably not, as they are in reality, be supported.  Both this
mythical, and today's real, GBE caters to its GBEL by, sometimes,
scrambling around, cleaning up after itself--after discovering that
assumptions it made earlier during code generation are incorrect.
That's not a great design, since it indicates significant code paths
that might be rarely tested but used in some key production
environments.)

   So, the FFE handles these discrepancies--between the order in which
it discovers facts about the code it is compiling, and the order in
which the GBEL and GBE support such discoveries--by performing what
amounts to two passes over each program unit.

   (A few ambiguities can remain at that point, such as whether, given
`EXTERNAL BAZ' and no other reference to `BAZ' in the program unit, it
is a subroutine, a function, or a block-data--which, in C-speak,
governs its declared return type.  Fortunately, these distinctions are
easily finessed for the procedure, library, and object-file interfaces
supported by `g77'.)


File: g77.info,  Node: Challenges Posed,  Next: Transforming Statements,  Prev: Two-pass Design,  Up: Front End

21.5 Challenges Posed
=====================

Consider the following Fortran code, which uses various extensions
(including some to Fortran 90):

     SUBROUTINE X(A)
     CHARACTER*(*) A
     COMPLEX CFUNC
     INTEGER*2 CLOCKS(200)
     INTEGER IFUNC

     CALL SYSTEM_CLOCK (CLOCKS (IFUNC (CFUNC ('('//A//')'))))

   The above poses the following challenges to any Fortran compiler
that uses run-time interfaces, and a run-time library, roughly similar
to those used by `g77':

   * Assuming the library routine that supports `SYSTEM_CLOCK' expects
     to set an `INTEGER*4' variable via its `COUNT' argument, the
     compiler must make available to it a temporary variable of that
     type.

   * Further, after the `SYSTEM_CLOCK' library routine returns, the
     compiler must ensure that the temporary variable it wrote is
     copied into the appropriate element of the `CLOCKS' array.  (This
     assumes the compiler doesn't just reject the code, which it should
     if it is compiling under some kind of a "strict" option.)

   * To determine the correct index into the `CLOCKS' array, (putting
     aside the fact that the index, in this particular case, need not
     be computed until after the `SYSTEM_CLOCK' library routine
     returns), the compiler must ensure that the `IFUNC' function is
     called.

     That requires evaluating its argument, which requires, for `g77'
     (assuming `-ff2c' is in force), reserving a temporary variable of
     type `COMPLEX' for use as a repository for the return value being
     computed by `CFUNC'.

   * Before invoking `CFUNC', is argument must be evaluated, which
     requires allocating, at run time, a temporary large enough to hold
     the result of the concatenation, as well as actually performing
     the concatenation.

   * The large temporary needed during invocation of `CFUNC' should,
     ideally, be deallocated (or, at least, left to the GBE to dispose
     of, as it sees fit) as soon as `CFUNC' returns, which means before
     `IFUNC' is called (as it might need a lot of dynamically allocated
     memory).

   `g77' currently doesn't support all of the above, but, so that it
might someday, it has evolved to handle at least some of the above
requirements.

   Meeting the above requirements is made more challenging by
conforming to the requirements of the GBEL/GBE combination.


File: g77.info,  Node: Transforming Statements,  Next: Transforming Expressions,  Prev: Challenges Posed,  Up: Front End

21.6 Transforming Statements
============================

Most Fortran statements are given their own block, and, for temporary
variables they might need, their own scope.  (A block is what
distinguishes `{ foo (); }' from just `foo ();' in C.  A scope is
included with every such block, providing a distinct name space for
local variables.)

   Label definitions for the statement precede this block, so `10 PRINT
*, I' is handled more like `fl10: { ... }' than `{ fl10: ... }' (where
`fl10' is just a notation meaning "Fortran Label 10" for the purposes
of this document).

* Menu:

* Statements Needing Temporaries::
* Transforming DO WHILE::
* Transforming Iterative DO::
* Transforming Block IF::
* Transforming SELECT CASE::


File: g77.info,  Node: Statements Needing Temporaries,  Next: Transforming DO WHILE,  Up: Transforming Statements

21.6.1 Statements Needing Temporaries
-------------------------------------

Any temporaries needed during, but not beyond, execution of a Fortran
statement, are made local to the scope of that statement's block.

   This allows the GBE to share storage for these temporaries among the
various statements without the FFE having to manage that itself.

   (The GBE could, of course, decide to optimize management of these
temporaries.  For example, it could, theoretically, schedule some of
the computations involving these temporaries to occur in parallel.
More practically, it might leave the storage for some temporaries
"live" beyond their scopes, to reduce the number of manipulations of
the stack pointer at run time.)

   Temporaries needed across distinct statement boundaries usually are
associated with Fortran blocks (such as `DO'/`END DO').  (Also, there
might be temporaries not associated with blocks at all--these would be
in the scope of the entire program unit.)

   Each Fortran block _should_ get its own block/scope in the GBE.
This is best, because it allows temporaries to be more naturally
handled.  However, it might pose problems when handling labels (in
particular, when they're the targets of `GOTO's outside the Fortran
block), and generally just hassling with replicating parts of the `gcc'
front end (because the FFE needs to support an arbitrary number of
nested back-end blocks if each Fortran block gets one).

   So, there might still be a need for top-level temporaries, whose
"owning" scope is that of the containing procedure.

   Also, there seems to be problems declaring new variables after
generating code (within a block) in the back end, leading to, e.g.,
`label not defined before binding contour' or similar messages, when
compiling with `-fstack-check' or when compiling for certain targets.

   Because of that, and because sometimes these temporaries are not
discovered until in the middle of of generating code for an expression
statement (as in the case of the optimization for `X**I'), it seems
best to always pre-scan all the expressions that'll be expanded for a
block before generating any of the code for that block.

   This pre-scan then handles discovering and declaring, to the back
end, the temporaries needed for that block.

   It's also important to treat distinct items in an I/O list as
distinct statements deserving their own blocks.  That's because there's
a requirement that each I/O item be fully processed before the next one,
which matters in cases like `READ (*,*), I, A(I)'--the element of `A'
read in the second item _must_ be determined from the value of `I' read
in the first item.


File: g77.info,  Node: Transforming DO WHILE,  Next: Transforming Iterative DO,  Prev: Statements Needing Temporaries,  Up: Transforming Statements

21.6.2 Transforming DO WHILE
----------------------------

`DO WHILE(expr)' _must_ be implemented so that temporaries needed to
evaluate `expr' are generated just for the test, each time.

   Consider how `DO WHILE (A//B .NE. 'END'); ...; END DO' is
transformed:

     for (;;)
       {
         int temp0;

         {
           char temp1[large];

           libg77_catenate (temp1, a, b);
           temp0 = libg77_ne (temp1, 'END');
         }

         if (! temp0)
           break;

         ...
       }

   In this case, it seems like a time/space tradeoff between allocating
and deallocating `temp1' for each iteration and allocating it just once
for the entire loop.

   However, if `temp1' is allocated just once for the entire loop, it
could be the wrong size for subsequent iterations of that loop in cases
like `DO WHILE (A(I:J)//B .NE. 'END')', because the body of the loop
might modify `I' or `J'.

   So, the above implementation is used, though a more optimal one can
be used in specific circumstances.


File: g77.info,  Node: Transforming Iterative DO,  Next: Transforming Block IF,  Prev: Transforming DO WHILE,  Up: Transforming Statements

21.6.3 Transforming Iterative DO
--------------------------------

An iterative `DO' loop (one that specifies an iteration variable) is
required by the Fortran standards to be implemented as though an
iteration count is computed before entering the loop body, and that
iteration count used to determine the number of times the loop body is
to be performed (assuming the loop isn't cut short via `GOTO' or
`EXIT').

   The FFE handles this by allocating a temporary variable to contain
the computed number of iterations.  Since this variable must be in a
scope that includes the entire loop, a GBEL block is created for that
loop, and the variable declared as belonging to the scope of that block.


File: g77.info,  Node: Transforming Block IF,  Next: Transforming SELECT CASE,  Prev: Transforming Iterative DO,  Up: Transforming Statements

21.6.4 Transforming Block IF
----------------------------

Consider:

     SUBROUTINE X(A,B,C)
     CHARACTER*(*) A, B, C
     LOGICAL LFUNC

     IF (LFUNC (A//B)) THEN
       CALL SUBR1
     ELSE IF (LFUNC (A//C)) THEN
       CALL SUBR2
     ELSE
       CALL SUBR3
     END

   The arguments to the two calls to `LFUNC' require dynamic allocation
(at run time), but are not required during execution of the `CALL'
statements.

   So, the scopes of those temporaries must be within blocks inside the
block corresponding to the Fortran `IF' block.

   This cannot be represented "naturally" in vanilla C, nor in GBEL.
The `if', `elseif', `else', and `endif' constructs provided by both
languages must, for a given `if' block, share the same C/GBE block.

   Therefore, any temporaries needed during evaluation of `expr' while
executing `ELSE IF(expr)' must either have been predeclared at the top
of the corresponding `IF' block, or declared within a new block for
that `ELSE IF'--a block that, since it cannot contain the `else' or
`else if' itself (due to the above requirement), actually implements
the rest of the `IF' block's `ELSE IF' and `ELSE' statements within an
inner block.

   The FFE takes the latter approach.


File: g77.info,  Node: Transforming SELECT CASE,  Prev: Transforming Block IF,  Up: Transforming Statements

21.6.5 Transforming SELECT CASE
-------------------------------

`SELECT CASE' poses a few interesting problems for code generation, if
efficiency and frugal stack management are important.

   Consider `SELECT CASE (I('PREFIX'//A))', where `A' is
`CHARACTER*(*)'.  In a case like this--basically, in any case where
largish temporaries are needed to evaluate the expression--those
temporaries should not be "live" during execution of any of the `CASE'
blocks.

   So, evaluation of the expression is best done within its own block,
which in turn is within the `SELECT CASE' block itself (which contains
the code for the CASE blocks as well, though each within their own
block).

   Otherwise, we'd have the rough equivalent of this pseudo-code:

     {
       char temp[large];

       libg77_catenate (temp, 'prefix', a);

       switch (i (temp))
         {
         case 0:
           ...
         }
     }

   And that would leave temp[large] in scope during the CASE blocks
(although a clever back end *could* see that it isn't referenced in
them, and thus free that temp before executing the blocks).

   So this approach is used instead:

     {
       int temp0;

       {
         char temp1[large];

         libg77_catenate (temp1, 'prefix', a);
         temp0 = i (temp1);
       }

       switch (temp0)
         {
         case 0:
           ...
         }
     }

   Note how `temp1' goes out of scope before starting the switch, thus
making it easy for a back end to free it.

   The problem _that_ solution has, however, is with `SELECT
CASE('prefix'//A)' (which is currently not supported).

   Unless the GBEL is extended to support arbitrarily long character
strings in its `case' facility, the FFE has to implement `SELECT CASE'
on `CHARACTER' (probably excepting `CHARACTER*1') using a cascade of
`if', `elseif', `else', and `endif' constructs in GBEL.

   To prevent the (potentially large) temporary, needed to hold the
selected expression itself (`'prefix'//A'), from being in scope during
execution of the `CASE' blocks, two approaches are available:

   * Pre-evaluate all the `CASE' tests, producing an integer ordinal
     that is used, a la `temp0' in the earlier example, as if `SELECT
     CASE(temp0)' had been written.

     Each corresponding `CASE' is replaced with `CASE(I)', where I is
     the ordinal for that case, determined while, or before, generating
     the cascade of `if'-related constructs to cope with `CHARACTER'
     selection.

   * Make `temp0' above just large enough to hold the longest `CASE'
     string that'll actually be compared against the expression (in
     this case, `'prefix'//A').

     Since that length must be constant (because `CASE' expressions are
     all constant), it won't be so large, and, further, `temp1' need
     not be dynamically allocated, since normal `CHARACTER' assignment
     can be used into the fixed-length `temp0'.

   Both of these solutions require `SELECT CASE' implementation to be
changed so all the corresponding `CASE' statements are seen during the
actual code generation for `SELECT CASE'.


File: g77.info,  Node: Transforming Expressions,  Next: Internal Naming Conventions,  Prev: Transforming Statements,  Up: Front End

21.7 Transforming Expressions
=============================

The interactions between statements, expressions, and subexpressions at
program run time can be viewed as:

     ACTION(EXPR)

   Here, ACTION is the series of steps performed to effect the
statement, and EXPR is the expression whose value is used by ACTION.

   Expanding the above shows a typical order of events at run time:

     Evaluate EXPR
     Perform ACTION, using result of evaluation of EXPR
     Clean up after evaluating EXPR

   So, if evaluating EXPR requires allocating memory, that memory can
be freed before performing ACTION only if it is not needed to hold the
result of evaluating EXPR.  Otherwise, it must be freed no sooner than
after ACTION has been performed.

   The above are recursive definitions, in the sense that they apply to
subexpressions of EXPR.

   That is, evaluating EXPR involves evaluating all of its
subexpressions, performing the ACTION that computes the result value of
EXPR, then cleaning up after evaluating those subexpressions.

   The recursive nature of this evaluation is implemented via
recursive-descent transformation of the top-level statements, their
expressions, _their_ subexpressions, and so on.

   However, that recursive-descent transformation is, due to the nature
of the GBEL, focused primarily on generating a _single_ stream of code
to be executed at run time.

   Yet, from the above, it's clear that multiple streams of code must
effectively be simultaneously generated during the recursive-descent
analysis of statements.

   The primary stream implements the primary ACTION items, while at
least two other streams implement the evaluation and clean-up items.

   Requirements imposed by expressions include:

   * Whether the caller needs to have a temporary ready to hold the
     value of the expression.

   * Other stuff???


File: g77.info,  Node: Internal Naming Conventions,  Prev: Transforming Expressions,  Up: Front End

21.8 Internal Naming Conventions
================================

Names exported by FFE modules have the following (regular-expression)
forms.  Note that all names beginning `ffeMOD' or `FFEMOD', where MOD
is lowercase or uppercase alphanumerics, respectively, are exported by
the module `ffeMOD', with the source code doing the exporting in
`MOD.h'.  (Usually, the source code for the implementation is in
`MOD.c'.)

   Identifiers that don't fit the following forms are not considered
exported, even if they are according to the C language.  (For example,
they might be made available to other modules solely for use within
expansions of exported macros, not for use within any source code in
those other modules.)

`ffeMOD'
     The single typedef exported by the module.

`FFEUMOD_[A-Z][A-Z0-9_]*'
     (Where UMOD is the uppercase for of MOD.)

     A `#define' or `enum' constant of the type `ffeMOD'.

`ffeMOD[A-Z][A-Z][a-z0-9]*'
     A typedef exported by the module.

     The portion of the identifier after `ffeMOD' is referred to as
     `ctype', a capitalized (mixed-case) form of `type'.

`FFEUMOD_TYPE[A-Z][A-Z0-9_]*[A-Z0-9]?'
     (Where UMOD is the uppercase for of MOD.)

     A `#define' or `enum' constant of the type `ffeMODTYPE', where
     TYPE is the lowercase form of CTYPE in an exported typedef.

`ffeMOD_VALUE'
     A function that does or returns something, as described by VALUE
     (see below).

`ffeMOD_VALUE_INPUT'
     A function that does or returns something based primarily on the
     thing described by INPUT (see below).

   Below are names used for VALUE and INPUT, along with their
definitions.

`col'
     A column number within a line (first column is number 1).

`file'
     An encapsulation of a file's name.

`find'
     Looks up an instance of some type that matches specified criteria,
     and returns that, even if it has to create a new instance or crash
     trying to find it (as appropriate).

`initialize'
     Initializes, usually a module.  No type.

`int'
     A generic integer of type `int'.

`is'
     A generic integer that contains a true (nonzero) or false (zero)
     value.

`len'
     A generic integer that contains the length of something.

`line'
     A line number within a source file, or a global line number.

`lookup'
     Looks up an instance of some type that matches specified criteria,
     and returns that, or returns nil.

`name'
     A `text' that points to a name of something.

`new'
     Makes a new instance of the indicated type.  Might return an
     existing one if appropriate--if so, similar to `find' without
     crashing.

`pt'
     Pointer to a particular character (line, column pairs) in the
     input file (source code being compiled).

`run'
     Performs some herculean task.  No type.

`terminate'
     Terminates, usually a module.  No type.

`text'
     A `char *' that points to generic text.


File: g77.info,  Node: Diagnostics,  Next: Keyword Index,  Prev: Front End,  Up: Top

22 Diagnostics
**************

Some diagnostics produced by `g77' require sufficient explanation that
the explanations are given below, and the diagnostics themselves
identify the appropriate explanation.

   Identification uses the GNU Info format--specifically, the `info'
command that displays the explanation is given within square brackets
in the diagnostic.  For example:

     foo.f:5: Invalid statement [info -f g77 M FOOEY]

   More details about the above diagnostic is found in the `g77' Info
documentation, menu item `M', submenu item `FOOEY', which is displayed
by typing the UNIX command `info -f g77 M FOOEY'.

   Other Info readers, such as EMACS, may be just as easily used to
display the pertinent node.  In the above example, `g77' is the Info
document name, `M' is the top-level menu item to select, and, in that
node (named `Diagnostics', the name of this chapter, which is the very
text you're reading now), `FOOEY' is the menu item to select.

* Menu:

* CMPAMBIG::    Ambiguous use of intrinsic.
* EXPIMP::      Intrinsic used explicitly and implicitly.
* INTGLOB::     Intrinsic also used as name of global.
* LEX::         Various lexer messages
* GLOBALS::     Disagreements about globals.
* LINKFAIL::    When linking `f771' fails.
* Y2KBAD::      Use of non-Y2K-compliant intrinsic.

