| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
To find out about major bugs discovered in the current release and possible workarounds for them, see ftp://alpha.gnu.org/g77.plan.
(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
section `Known Causes of Trouble with GNU CC' in Using and Porting GNU CC.)
16.1 Bugs Not In GNU Fortran Bugs really in other programs or elsewhere. 16.2 Known Bugs In GNU Fortran Bugs known to be in this version of g77.16.3 Missing Features Features we already know we want to add later. 16.4 Disappointments and Misunderstandings Regrettable things we can't change. 16.5 Certain Changes We Don't Want to Make Things we think are right, but some others disagree. 16.6 Warning Messages and Error Messages Which problems in your code get warnings, and which get errors.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
See section 15. Collected Fortran Wisdom, for information on behavior of Fortran programs, and the programs that compile them, that might be thought to indicate bugs.
16.1.1 Signal 11 and Friends Strange behavior by any software. 16.1.2 Cannot Link Fortran Programs Unresolved references. 16.1.3 Large Common Blocks Problems on older GNU/Linux systems. 16.1.4 Debugger Problems When the debugger crashes. 16.1.5 NeXTStep Problems Misbehaving executables. 16.1.6 Stack Overflow More misbehaving executables. 16.1.7 Nothing Happens Less behaving executables. 16.1.8 Strange Behavior at Run Time Executables misbehaving due to bugs in your program. 16.1.9 Floating-point Errors The results look wrong, but....
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This is a bug in older versions of ld, fixed in
more recent versions of binutils, such as version 2.6.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.)
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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).)
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
See section 16.1 Bugs Not In GNU Fortran, 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.)
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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 behaviour.
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'.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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. See section 16.5.4 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/, and there is a supplemented version, in PostScript form, at http://www.validgh.com/goldberg/paper.ps.
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/. http://www.linuxsupportline.com/%7Ebillm/ has a brief guide to IEEE 754, a somewhat x86-GNU/Linux-specific FAQ, and library code for GNU/Linux x86 systems.
The supplement to the PostScript-formatted Goldberg document, referenced above, is available in HTML format. See `Differences Among IEEE 754 Implementations' by Doug Priest, available online at http://www.validgh.com/goldberg/addendum.html. 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.
See section 15.4.10 Floating-point precision, regarding IEEE 754 conformance.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This section identifies bugs that g77 users
might run into in the GCC-3.0 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 News About GNU Fortran.
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://www.gnu.org/software/gcc/onlinedocs/g77_bugs.html.
Follow the "Known Bugs" link.
The following information was last updated on 2001-06-10:
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).
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.
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.
This is to be fixed in version 0.6, when g77 will use the
gcc back end's constant-handling mechanisms to replace its own.
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. This is to be mitigated somewhat in version 0.6.
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.
g77 didn't emit information on
variable and array members of common blocks and equivalences
for use with a debugger (the `-g' command-line option).
As of the version of g77 shipped with version 3.0 of
GCC, this is corrected.
As of Version 0.5.19, a temporary kludge solution is provided whereby some rudimentary information on a member is written as a string that is the member's value as a character string.
See section Options for Code Generation Conventions, for information on the `-fdebug-kludge' option.
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.
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. Version 0.6 should solve most or all remaining problems (such as cross-compiling involving 64-bit machines).
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.
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.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.)
GNU Fortran language:
GNU Fortran dialects:
New facilities:
Better diagnostics:
Run-time facilities:
16.3.47 Uninitialized Variables at Run Time 16.3.48 Portable Unformatted Files 16.3.49 Better List-directed I/O 16.3.50 Default to Console I/O
Debugging:
16.3.51 Labels Visible to Debugger
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
PARAMETER Statements
g77 doesn't allow intrinsics in PARAMETER statements.
This feature is considered to be absolutely vital, even though it
is not standard-conforming, and is scheduled for version 0.6.
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.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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') |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
SELECT CASE on CHARACTER Type
Character-type selector/cases for SELECT CASE currently
are not supported.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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).
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
g77 doesn't fully support INTEGER*2, LOGICAL*1,
and similar.
Version 0.6 will provide full support for this very
popular set of features.
In the meantime, version 0.5.18 provides rudimentary support
for them.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
This is scheduled for version 0.6.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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)) |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
See section 8.11 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.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.)
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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>) |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
g77 needs to provide some way, a la gcc, for g77
code to specify explicit assembler code.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The Q edit descriptor in FORMATs 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. See section 8.11.9.104 FGetC Intrinsic (subroutine).
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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).
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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'.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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 |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
An option such as `-fugly-char' should be provided to allow
REAL*8 A1 DATA A1 / '12345678' / |
and:
REAL*8 A1 A1 = 'ABCDEFGH' |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
POSIX Standard
g77 should support the POSIX standard for Fortran.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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 behaviour is normally inherited from the system-dependent startup
code, though some targets, such as the Alpha, have code generation
options which change the behaviour.
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 |
g77 command line
when linking.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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).
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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:
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.
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.
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.
Worth considering after g77 0.6 is considered
pretty solid.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.)
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
`-Wconversion' and related should flag places where non-standard conversions are found. Perhaps much of this would be part of `-Wugly*'.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
| [ < ] | [ > ] |