Most users of
g77 can be divided into two camps:
g77to 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
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.
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:
g77to try and put variables and arrays on the stack (or in fast registers) where possible and reasonable. This tends to make programs faster.
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
that is, it generates an actual procedure having the appropriate name.
The procedure does nothing but return immediately if it happens to be
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.
g77 outputs in the data section a static pointer to the
external name `FOO'.)
g77 currently uses to make this work is
one of the few things not compatible with
f2c as currently
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
The upshot is that you shouldn't mix `f2c' and
this particular case.
If you use f2c to compile `BLOCK DATA FOO',
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
Aside from the usual `gcc' options, such as `-O', `-ffast-math', and so on, consider trying:
f2c. (Note that
libf2cis not an example of code that is compiled using
f2c---it is compiled by a C compiler, usually
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 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.
See section Overly Convenient Command-line 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.
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 options that might be useful for
tracking down bugs in such programs.
See section Option Summary, for a summary of these and other
options, and cross-references for each such option to
the pertinent material in this manual.
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
g77and other compilers are more likely to follow the programmer's expectations, might be worthwhile, especially if such changes make the program work better.
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 `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:
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', the following loop will not work:
DO I = -2000000000, 2000000000
Although the start and end values are well within the range of `INTEGER', the trip count is not. The expected trip count is 40000000001, which is outside the range of `INTEGER' 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
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
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, such as a `REAL' or `DOUBLE PRECISION' 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' are never executed.
However, this is the output of running the above program
as compiled by
g77 on a 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 Linux
ix86 are used.
On other systems, an apparently more accurate trip count
of 31 might result, but, nevertheless,
faithfully following the Fortran standard, and the result
is not what the author of the sample program above
(Such other systems might, for different values in the `DATA'
statement, violate the other programmer's expectation,
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' or `DOUBLE PRECISION' iteration
variables is not recommended.
Such use can be caught by specifying `-Wsurprising'.
See section Options to Request or Suppress Warnings, for more information on this
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
was created if
f2c already existed.
This section gives some basic answers to these questions, though it is not intended to be comprehensive.
g77 offers several extensions to the Fortran language that
f2c offers a few that
g77 doesn't, like
fairly complete support for `INTEGER*2'.
It is expected that
g77 will offer some or all of these missing
features at some time in the future.
(Version 0.5.18 of
g77 offers some rudimentary support for some
of these features.)
g77 offers a whole bunch of compiler options that
f2c offers a few that
g77 doesn't, like an
option to generate code to check array subscripts at run time.
It is expected that
g77 will offer some or all of these
missing options at some time in the future.
Saving the steps of writing and then rereading C code is a big reason
g77 should be able to compile code much faster than using
f2c in conjunction with the equivalent invocation of
However, due to
g77's youth, lots of self-checking is still being
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,
is noticably faster compiling many Fortran source files than using
f2c in conjunction with
g77 has the potential to better optimize code than
gcc is used to compile the output of
f2c must necessarily
translate Fortran into a somewhat lower-level language (C) that cannot
preserve all the information that is potentially useful for optimization,
g77 can gather, preserve, and transmit that information directly
to the GBE.
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
can generate code that is faster than
It is hoped that version 0.5.18 of
g77 will offer default
settings and options that allow for better program speed, though
it is not yet known whether these same options, when applied to
gcc compilation of
f2c output, will improve the
speed of programs compiled using that method as well.
g77 compiles directly to assembler code like
instead of translating to an intermediate language (C) as does
support for debugging can be better for
g77 might be somewhat more "native" in terms of
debugging support than
gcc, there still are a lot
of things "not quite right".
Many of the important ones should be resolved in the near future.
g77 doesn't have to worry about reserved names
Given `FOR = WHILE',
f2c must necessarily
translate this to something other than
`for = while;', because C reserves those words.
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)
g77 user should be able to access the variables directly, by name,
without having to traverse C-like structures and unions, while
is unlikely to ever offer this ability (due to limitations in the
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
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
g77 could do many of the things
to get things working at least as well as
the maintainers have tended to prefer making
g77 work the
way they think it is supposed to, and find help improving the
other products (the GBE of
gdb; and so on)
to get things working properly.
To avoid the extensive hassle that would be needed to avoid this,
f2c uses C character constants to encode character and Hollerith
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,
g77 simply asks for fewer zeros from the operating
Go to the first, previous, next, last section, table of contents.