GNU Fortran supports a variety of extensions to, and dialects
of, the Fortran language.
Its primary base is the ANSI FORTRAN 77 standard, currently available on
the network at @url{http://kumo.swcp.com/fortran/F77_std/f77_std.html}
or in @url{ftp://ftp.ast.cam.ac.uk/pub/michael/}.
It offers some extensions that are popular among users
of UNIX f77
and f2c
compilers, some that
are popular among users of other compilers (such as Digital
products), some that are popular among users of the
newer Fortran 90 standard, and some that are introduced
by GNU Fortran.
Part of what defines a particular implementation of a Fortran
system, such as g77
, is the particular characteristics
of how it supports types, constants, and so on.
Much of this is left up to the implementation by the various
Fortran standards and accepted practice in the industry.
g77
.
GNU Fortran supports ANSI FORTRAN 77 with the following caveats:
CHARACTER*(*) CFUNC EXTERNAL CFUNC CALL FOO(CFUNC) ENDIt isn't clear whether the standard considers this conforming. Note that it is unlikely that any production Fortran code tries to use this unsupported construct.
SUBROUTINE BAR(CFUNC) CHARACTER*(*) CFUNC EXTERNAL CFUNC CALL FOO(CFUNC) ENDIt isn't clear whether the standard considers this conforming. Note that it is unlikely that any production Fortran code tries to use this unsupported construct.
g77
:
DATA ((A(I, I), I= 1, 10), I= 1, 10)/.../This also is disallowed by Fortran 90, as it offers no additional capabilities and would have a variety of possible meanings. Note that it is very unlikely that any production Fortran code tries to use this unsupported construct.
g77
:
DATA (A, I= 1, 1)/1./This also is disallowed by Fortran 90, as FORTRAN 77's more permissive requirements offer no additional capabilities. However,
g77
doesn't necessarily diagnose all cases
where this requirement is not met.
Note that it is very unlikely that any production Fortran code
tries to use this unsupported construct.
In summary, the only ANSI FORTRAN 77 features g77
doesn't
support are those that are probably rarely used in actual code,
some of which are explicitly disallowed by the Fortran 90 standard.
GNU Fortran supports ANSI FORTRAN 77 plus:
f2c
intrinsics (`AND', `OR', `LSHIFT',
`RSHIFT', and so on).
f2c
varieties).
f2c
features.
f2c
).
When `-ff90' is specified, the language dialect changes as follows:
g77
.
g77
does
not yet support that interpretation).
Fortran implementations have a fair amount of freedom given them by the standard as far as how much storage space is used and how much precision is offered by the various types such as `LOGICAL', `INTEGER', `REAL', `DOUBLE PRECISION', `COMPLEX', and `CHARACTER'. Further, many compilers offer so-called `*n' notation, but the interpretation of n varies across compilers and target architectures.
The standard requires that `LOGICAL', `INTEGER', and `REAL' occupy the same amount of storage space, and that `COMPLEX' and `DOUBLE PRECISION' take twice as much storage space as `REAL'. Further, it requires that `COMPLEX' entities be ordered such that when a `COMPLEX' variable is storage-associated (such as via `EQUIVALENCE') with a two-element `REAL' array named `R', `R(1)' corresponds to the real element and `R(2)' to the imaginary element of the `COMPLEX' variable. No particular requirements as to precision of any of these are placed on the implementation, nor is the relationship of storage sizes of these types to the `CHARACTER' type specified by the standard.
g77
follows the above requirements, warning when compiling
a program requires placement of items in memory that contradict the
requirements of the target architecture.
(For example, a program can require placement of a `DOUBLE PRECISION'
on a boundary that is not an even multiple of its size, but still an
even multiple of the size of a `REAL' variable.
On some target architectures, using the canonical
mapping of Fortran types to underlying architectural types, such
placement is prohibited by the machine definition or
the Application Binary Interface (ABI) in force for
the configuration defined for building gcc
and g77
.
g77
warns about such
situations when it encounters them.)
g77
follows consistent rules for configuring the mapping between Fortran
types, including the `*n' notation, and the underlying architectural
types as accessed by a similarly-configured applicable version of the
gcc
compiler.
These rules offer a widely portable, consistent Fortran/C
environment, although they might well conflict with the expectations of
users of Fortran compilers designed and written for particular
architectures.
These rules are based on the configuration that is in force for the
version of gcc
built in the same release as g77
(and
which was therefore used to build both the g77
compiler
components and the libf2c
run-time library):
REAL
DOUBLE PRECISION
INTEGER
LOGICAL
gcc
type as `INTEGER'.
COMPLEX
DOUBLE COMPLEX
numeric-type*n
gcc
type occupies n times the storage
space of a gcc
`char' item.
numeric-type(KIND=n)
g77
---avoid writing code depending
on them.
Other types supported by g77
are derived from gcc types such as `char', `short',
`int', `long int', `long long int', `long double',
and so on.
That is, whatever types `gcc' already supports, g77
supports
now or probably will support in a future version.
The rules for the `numeric-type*n' notation
apply to these types,
and new values for `numeric-type(KIND=n)' will be
assigned in a way that encourages clarity, consistency, and portability.
g77
strictly assigns types to all constants not
documented as "typeless" (typeless constants including `'1'Z',
for example).
Context is never a determining factor for the type, and hence
the interpretation, of a typed constant.
Examples: `1' is always type `INTEGER',
`9.435784839284958' is always type `REAL' (even if the
additional precision specified is lost, and even when used in a `DOUBLE
PRECISION' context), `1E0' is always type `REAL', and `1D0'
is always type `DOUBLE PRECISION'.
Many other Fortran compilers attempt to assign types to typed constants
based on their context.
This results in hard-to-find bugs, nonportable
code, and is not in the spirit (though it strictly follows the letter)
of the 77 and 90 standards.
g77
will not support these dangerous
semantics, but might offer, in a future release, explicit constructs by
which a wider variety of typeless constants may be specified, and/or
user-requested warnings indicating places where g77
might differ
from how other compilers assign types to constants.
The `-ffree-form' (aka `-fno-fixed-form') and `-ffixed-form' (aka `-fno-free-form') command-line options govern how the source file is interpreted. Fixed form corresponds to classic ANSI FORTRAN 77 (plus popular extensions, such as allowing tabs) and Fortran 90's fixed form. Free form corresponds to Fortran 90's free form (though possibly not entirely up-to-date, and without complaining about some things that for which Fortran 90 requires diagnostics, such as `R = 3 . 1').
The way a Fortran compiler views source files depends entirely on the
implementation choices made for the compiler.
GNU Fortran currently tries to be somewhat like a few popular compilers
(f2c
, DEC Fortran, and so on), though a cleaner default
definition along with more
flexibility offered by command-line options is likely to be offered
in version 0.6.
Here are some facts regarding the way g77
interprets source lines:
f2c
, which seems to treat them as
spaces outside character/Hollerith constants, and encodes them as `\r'
inside such constants.
f2c
, which encodes tabs as
`\t' (the ASCII TAB character) inside character
and Hollerith constants, but nevertheless seems to treat the column
position as if it had been affected by the canonical tab positioning.
g77
effectively
translates tabs to the appropriate number of spaces (a la the default
for the UNIX expand
command) before doing any other processing, other
than (currently) noting whether a tab was found on a line and using this
info to decide how to interpret the length of the line and continued
constants.
Note that this default behavior probably will change for version 0.6,
when it will presumably be available via a command-line option.
The default as of version 0.6 is planned to be a "pure visual"
model, where tabs are immediately
converted to spaces and otherwise have no effect, so the way a typical
user sees source lines produces a consistent result no matter how the
spacing in those source lines is actually implemented via tabs, spaces,
and trailing tabs/spaces before newline.
Command-line options are likely to be added to specify whether all or
just-tabbed lines are to be extended to 132 or full input-line length,
and perhaps even an option will be added to specify the truncated-line
behavior to which some Digital compilers default (and which affects
the way continued character/Hollerith constants are interpreted).
g77
might someday offer an option to warn about cases where differences
might be seen as a result of this treatment, and perhaps an option to
specify the alternate behavior as well.
Note that this padding cannot apply to lines that are effectively of
infinite length--such lines are specified using command-line options
like `-ffixed-line-length-none', for example.
The `-fpedantic' command-line option specifies that g77
is to warn about certain non-standard constructs.
This is useful for finding
some extensions g77
accepts that other compilers might not accept.
(Note that the `-pedantic' and `-pedantic-errors' options
always imply `-fpedantic'.)
With `-ff90' in force along with `-fpedantic', some constructs are accepted that result in diagnostics when `-fno-f90' and `-fpedantic' are both in force. See section GNU Fortran Extensions, for information on those constructs.
The constructs for which g77
issues diagnostics when `-fpedantic'
and `-fno-f90' are in force are:
f2c
) allow the superfluous comma.
If `-fpedantic' is specified along with `-ff90', the following constructs result in diagnostics:
GNU Fortran offers the programmer way too much flexibility in deciding how source files are to be treated vis-a-vis uppercase and lowercase characters. There are 66 useful settings that affect case sensitivity, plus 10 settings that are nearly useless, with the remaining 116 settings being either redundant or useless.
None of these settings have any effect on the contents of comments (the text after a `c' or `C' in Column 1, for example) or of character or Hollerith constants. Note that things like the `E' in the statement `CALL FOO(3.2E10)' and the `TO' in `ASSIGN 10 TO LAB' are considered built-in keywords.
Low-level switches are identified in this discussion thusly:
Note 1: g77
eventually will support `NAMELIST' in a manner that is
consistent with these source switches--in the sense that input will be
expected to meet the same requirements as source code in terms
of matching symbol names and keywords (for the exponent letters).
Currently, however, `NAMELIST' is supported `libf2c', which uppercases `NAMELIST' input and symbol names for matching. This means not only that `NAMELIST' output currently shows symbol (and keyword) names in uppercase even if lower-case source conversion (option A2) is selected, but that `NAMELIST' cannot be adequately supported when source case preservation (option A0) is selected.
If A0 is selected, a warning message will be output for each `NAMELIST' statement to this effect. The behavior of the program is undefined at run time if two or more symbol names appear in a given `NAMELIST' such that the names are identical when converted to upper case (e.g. `NAMELIST /X/ VAR, Var, var'). For complete and total elegance, perhaps there should be a warning when option A2 is selected, since the output of NAMELIST is currently in uppercase but will someday be lowercase (when a `libg77' is written), but that seems to be overkill for a product in beta test.
Note 2: Rules for InitialCaps names are:
So `A', `Ab', `ABc', `AbC', and `Abc' are valid InitialCaps names, but `AB', `A2', and `ABC' are not. Note that most, but not all, built-in names meet these requirements--the exceptions are some of the two-letter format specifiers, such as `BN' and `BZ'.
Here are the names of the corresponding command-line options:
A0: -fsource-case-preserve A1: -fsource-case-upper A2: -fsource-case-lower B0: -fmatch-case-any B1: -fmatch-case-upper B2: -fmatch-case-lower B3: -fmatch-case-initcap C0: -fintrin-case-any C1: -fintrin-case-upper C2: -fintrin-case-lower C3: -fintrin-case-initcap D0: -fsymbol-case-any D1: -fsymbol-case-upper D2: -fsymbol-case-lower D3: -fsymbol-case-initcap
Useful combinations of the above settings, along with abbreviated option names that set some of these combinations all at once:
1: A0-- B0-- C0-- D0-- -fcase-preserve 2: A0-- B0-- C0-- D-1-- 3: A0-- B0-- C0-- D--2- 4: A0-- B0-- C0-- D--3 5: A0-- B0-- C-1-- D0--- 6: A0-- B0-- C-1-- D-1-- 7: A0-- B0-- C-1-- D--2- 8: A0-- B0-- C-1-- D--3 9: A0-- B0-- C--2- D0--- 10: A0-- B0-- C--2- D-1-- 11: A0-- B0-- C--2- D--2- 12: A0-- B0-- C--2- D--3 13: A0-- B0-- C--3 D0--- 14: A0-- B0-- C--3 D-1-- 15: A0-- B0-- C--3 D--2- 16: A0-- B0-- C--3 D--3 17: A0-- B-1-- C0-- D0--- 18: A0-- B-1-- C0-- D-1-- 19: A0-- B-1-- C0-- D--2- 20: A0-- B-1-- C0-- D--3 21: A0-- B-1-- C-1-- D0--- 22: A0-- B-1-- C-1-- D-1-- -fcase-strict-upper 23: A0-- B-1-- C-1-- D--2- 24: A0-- B-1-- C-1-- D--3 25: A0-- B-1-- C--2- D0--- 26: A0-- B-1-- C--2- D-1-- 27: A0-- B-1-- C--2- D--2- 28: A0-- B-1-- C--2- D--3 29: A0-- B-1-- C--3 D0--- 30: A0-- B-1-- C--3 D-1-- 31: A0-- B-1-- C--3 D--2- 32: A0-- B-1-- C--3 D--3 33: A0-- B--2- C0-- D0--- 34: A0-- B--2- C0-- D-1-- 35: A0-- B--2- C0-- D--2- 36: A0-- B--2- C0-- D--3 37: A0-- B--2- C-1-- D0--- 38: A0-- B--2- C-1-- D-1-- 39: A0-- B--2- C-1-- D--2- 40: A0-- B--2- C-1-- D--3 41: A0-- B--2- C--2- D0--- 42: A0-- B--2- C--2- D-1-- 43: A0-- B--2- C--2- D--2- -fcase-strict-lower 44: A0-- B--2- C--2- D--3 45: A0-- B--2- C--3 D0--- 46: A0-- B--2- C--3 D-1-- 47: A0-- B--2- C--3 D--2- 48: A0-- B--2- C--3 D--3 49: A0-- B--3 C0-- D0--- 50: A0-- B--3 C0-- D-1-- 51: A0-- B--3 C0-- D--2- 52: A0-- B--3 C0-- D--3 53: A0-- B--3 C-1-- D0--- 54: A0-- B--3 C-1-- D-1-- 55: A0-- B--3 C-1-- D--2- 56: A0-- B--3 C-1-- D--3 57: A0-- B--3 C--2- D0--- 58: A0-- B--3 C--2- D-1-- 59: A0-- B--3 C--2- D--2- 60: A0-- B--3 C--2- D--3 61: A0-- B--3 C--3 D0--- 62: A0-- B--3 C--3 D-1-- 63: A0-- B--3 C--3 D--2- 64: A0-- B--3 C--3 D--3 -fcase-initcap 65: A-1- B01-- C01-- D01-- -fcase-upper 66: A--2 B0-2- C0-2- D0-2- -fcase-lower
Number 22 is the "strict" ANSI FORTRAN 77 model wherein all input (except comments, character constants, and Hollerith strings) must be entered in uppercase. Use `-fcase-strict-upper' to specify this combination.
Number 43 is like Number 22 except all input must be lowercase. Use `-fcase-strict-lower' to specify this combination.
Number 65 is the "classic" ANSI FORTRAN 77 model as implemented on many non-UNIX machines whereby all the source is translated to uppercase. Use `-fcase-upper' to specify this combination.
Number 66 is the "canonical" UNIX model whereby all the source is translated to lowercase. Use `-fcase-lower' to specify this combination.
There are a few nearly useless combinations:
67: A-1- B01-- C01-- D--2- 68: A-1- B01-- C01-- D--3 69: A-1- B01-- C--23 D01-- 70: A-1- B01-- C--23 D--2- 71: A-1- B01-- C--23 D--3 72: A--2 B01-- C0-2- D-1-- 73: A--2 B01-- C0-2- D--3 74: A--2 B01-- C-1-3 D0-2- 75: A--2 B01-- C-1-3 D-1-- 76: A--2 B01-- C-1-3 D--3
The above allow some programs to be compiled but with restrictions that make most useful programs impossible: Numbers 67 and 72 warn about any user-defined symbol names (such as `SUBROUTINE FOO'); Numbers 68 and 73 warn about any user-defined symbol names longer than one character that don't have at least one non-alphabetic character after the first; Numbers 69 and 74 disallow any references to intrinsics; and Numbers 70, 71, 75, and 76 are combinations of the restrictions in 67+69, 68+69, 72+74, and 73+74, respectively.
All redundant combinations are shown in the above tables anyplace where more than one setting is shown for a low-level switch. For example, `B0-2-' means either setting 0 or 2 is valid for switch B. The "proper" setting in such a case is the one that copies the setting of switch A--any other setting might slightly reduce the speed of the compiler, though possibly to an unmeasurable extent.
All remaining combinations are useless in that they prevent successful compilation of non-null source files (source files with something other than comments).
A given specific intrinsic belongs in one or more groups. Each group is deleted, disabled, hidden, or enabled by default or a command-line option. The meaning of each term follows.
The distinction between deleting and disabling a group is illustrated by the following example. Assume intrinsic `FOO' belongs only to group `FGR'. If group `FGR' is deleted, the following program unit will successfully compile, because `FOO()' will be seen as a reference to an external function named `FOO':
PRINT *, FOO() END
If group `FGR' is disabled, compiling the above program will produce diagnostics, either because the `FOO' intrinsic is improperly invoked or, if properly invoked, it is not enabled. To change the above program so it references an external function `FOO' instead of the disabled `FOO' intrinsic, add the following line to the top:
EXTERNAL FOO
So, deleting a group tells g77
to pretend as though the intrinsics in
that group do not exist at all, whereas disabling it tells g77
to
recognize them as (disabled) intrinsics in intrinsic-like contexts.
Hiding a group is like enabling it, but the intrinsic must be first named in an `INTRINSIC' statement to be considered a reference to the intrinsic rather than to an external procedure. This might be the "safest" way to treat a new group of intrinsics when compiling old code, because it allows the old code to be generally written as if those new intrinsics never existed, but to be changed to use them by inserting `INTRINSIC' statements in the appropriate places. However, it should be the goal of development to use `EXTERNAL' for all names of external procedures that might be intrinsic names.
If an intrinsic is in more than one group, it is enabled if any of its containing groups are enabled; if not so enabled, it is hidden if any of its containing groups are hidden; if not so hidden, it is disabled if any of its containing groups are disabled; if not so disabled, it is deleted. This extra complication is necessary because some intrinsics, such as `IBITS', belong to more than one group, and hence should be enabled if any of the groups to which they belong are enabled, and so on.
The groups are:
dcp
f2c
f2c
converter and/or libf2c
.
f90
mil
unix
vxt
The `-fvxt-not-f90' and `-ff90-not-vxt' command-line options
control how g77
interprets certain tokens and constructs that
have different meanings in VAX FORTRAN (circa v4) and Fortran 90.
(Generally, this manual uses the invented acronym VXT to refer
to many popular VAX FORTRAN extensions, though not necessarily
those that are specific to the VAX processor architecture or the
VMS operating system.
An extension offered by a Digital Fortran product that also is
offered by several other Fortran products for different kinds of
systems is probably going to be considered for inclusion in g77
someday, and is considered a VXT extension.)
When `-ff90-not-vxt' is specified, the following interpretations are made (and, when `-fvxt-not-f90' is in effect, the opposite interpretations are made):
g77
will produce a diagnostic instead of trying to
implement the VXT `TYPE' statement--which currently is not supported
either.)
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 exectable 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
.
Other compilers might or might not generate code that
is object-compatible with libf2c
and current g77
,
and some might offer such compatibility only when explicitly
selected via a command-line option to the compiler.
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', `COMPLEX', and
`DOUBLE COMPLEX' 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' functions return double,
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 not
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 either cause g77
to produce compatible code
(at the expense of the availability of some features and
performance), or at the very least trigger
compiler warning messages, in future versions of g77
.
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:
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.
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.
The `-fugly-*' command-line options determine whether certain features supported by VAX FORTRAN and other such compilers, but considered too ugly to be in code that can be changed to use safer and/or more portable constructs, are accepted. These are humorously referred to as "distensions", extensions that just plain look ugly in the harsh light of day.
The construct disabled via `-fno-ugly-args' is:
The construct enabled via `-fugly-assumed' is:
The construct enabled via `-fugly-comma' is:
The constructs disabled by `-fno-ugly-init' are:
PARAMETER (VAL='9A304FFE'X) REAL*8 STRING/8HOUTPUT00/ DATA VAR/4HABCD/
INTEGER IA CHARACTER BELL PARAMETER (IA = 'A') PARAMETER (BELL = 7)
IVAR = 4HABCD PRINT *, IMAX0(2HAB, 2HBA)
The above constructs, when used, can tend to result in non-portable code. But, they are widely used in existing Fortran code in ways that often are quite portable. Therefore, they are enabled by default.
The constructs enabled via `-fugly-logint' are:
The above constructs are disabled by default because use of them tends to lead to non-portable code. Even existing Fortran code that uses that often turns out to be non-portable, if not outright buggy.
Some of this is due to differences among implementations as far as how `.TRUE.' and `.FALSE.' are encoded as `INTEGER' values--Fortran code that assumes a particular coding is likely to use one of the above constructs, and is also likely to not work correctly on implementations using different encodings.
See section Equivalence Versus Equality, for more information.
Go to the first, previous, next, last section, table of contents.