The GNU Fortran compiler, g77
, supports programs written
in the GNU Fortran language and in some other dialects of Fortran.
Some aspects of how g77
works are universal regardless
of dialect, and yet are not properly part of the GNU Fortran
language itself.
These are described below.
Note: This portion of the documentation definitely needs a lot of work!
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
and range is offered by the various types such as LOGICAL(KIND=1)
,
INTEGER(KIND=1)
, REAL(KIND=1)
, REAL(KIND=2)
,
COMPLEX(KIND=1)
, 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(KIND=1)
, INTEGER(KIND=1)
,
and REAL(KIND=1)
occupy the same amount of storage space, and that COMPLEX(KIND=1)
and REAL(KIND=2)
take twice as much storage space as REAL(KIND=1)
.
Further, it requires that COMPLEX(KIND=1)
entities be ordered such that when a COMPLEX(KIND=1)
variable is
storage-associated (such as via EQUIVALENCE
)
with a two-element REAL(KIND=1)
array named `R', `R(1)'
corresponds to the real element and `R(2)' to the imaginary
element of the COMPLEX(KIND=1)
variable.
(Few requirements as to precision or ranges 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 REAL(KIND=2)
on a boundary that is not an even multiple of its size, but still an
even multiple of the size of a REAL(KIND=1)
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(KIND=1)
float
type.
REAL(KIND=2)
float
---usually, this is a double
.
INTEGER(KIND=1)
float
---usually, this is either
an int
or a long int
.
LOGICAL(KIND=1)
gcc
type as INTEGER(KIND=1)
.
INTEGER(KIND=2)
INTEGER(KIND=1)
---usually, this is either
a long int
or a long long int
.
LOGICAL(KIND=2)
gcc
type as INTEGER(KIND=2)
.
INTEGER(KIND=3)
gcc
type as signed char
.
LOGICAL(KIND=3)
gcc
type as INTEGER(KIND=3)
.
INTEGER(KIND=6)
INTEGER(KIND=3)
---usually, this is
a short
.
LOGICAL(KIND=6)
gcc
type as INTEGER(KIND=6)
.
COMPLEX(KIND=1)
REAL(KIND=1)
scalars (one for the real part followed by
one for the imaginary part).
COMPLEX(KIND=2)
REAL(KIND=2)
scalars.
numeric-type*n
CHARACTER
.)
Same as whatever gcc
type occupies n times the storage
space of a gcc
char
item.
DOUBLE PRECISION
REAL(KIND=2)
.
DOUBLE COMPLEX
COMPLEX(KIND=2)
.
Note that the above are proposed correspondences and might change
in future versions of 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).
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
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.
See section Context-Sensitive Constants, for more information on this issue.
g77
offers an ever-widening set of intrinsics.
Currently these all are procedures (functions and subroutines).
Some of these intrinsics are unimplemented, but their names reserved to reduce future problems with existing code as they are implemented. Others are implemented as part of the GNU Fortran language, while yet others are provided for compatibility with other dialects of Fortran but are not part of the GNU Fortran language.
To manage these distinctions, g77
provides intrinsic groups,
a facility that is simply an extension of the intrinsic groups provided
by the GNU Fortran language.
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.
INTRINSIC
statement)
are disallowed through that group.
INTRINSIC
statement.
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:
gnu
f2c
f2c
converter and/or libf2c
.
f90
mil
MVBITS
, IAND
, BTEST
, and so on).
unix
IARGC
, EXIT
, ERF
, and so on).
vxt
g77
supports intrinsics other than those in the GNU Fortran
language proper.
This set of intrinsics is described below.
CDAbs(A)
CDAbs: REAL(KIND=2)
function.
A: COMPLEX(KIND=2)
; scalar; INTENT(IN).
Intrinsic groups: f2c
, vxt
.
Description:
Archaic form of ABS()
that is specific
to one type for A.
See section Abs Intrinsic.
CDCos(X)
CDCos: COMPLEX(KIND=2)
function.
X: COMPLEX(KIND=2)
; scalar; INTENT(IN).
Intrinsic groups: f2c
, vxt
.
CDExp(X)
CDExp: COMPLEX(KIND=2)
function.
X: COMPLEX(KIND=2)
; scalar; INTENT(IN).
Intrinsic groups: f2c
, vxt
.
CDLog(X)
CDLog: COMPLEX(KIND=2)
function.
X: COMPLEX(KIND=2)
; scalar; INTENT(IN).
Intrinsic groups: f2c
, vxt
.
Description:
Archaic form of LOG()
that is specific
to one type for X.
See section Log Intrinsic.
CDSin(X)
CDSin: COMPLEX(KIND=2)
function.
X: COMPLEX(KIND=2)
; scalar; INTENT(IN).
Intrinsic groups: f2c
, vxt
.
CDSqRt(X)
CDSqRt: COMPLEX(KIND=2)
function.
X: COMPLEX(KIND=2)
; scalar; INTENT(IN).
Intrinsic groups: f2c
, vxt
.
CALL Date(Date)
Date: CHARACTER
; scalar; INTENT(OUT).
Intrinsic groups: vxt
.
Description:
Returns Date in the form `dd-mmm-yy', representing the numeric day of the month dd, a three-character abbreviation of the month name mmm and the last two digits of the year yy, e.g. `25-Nov-96'.
This intrinsic is not recommended, due to the year 2000 approaching. See section CTime Intrinsic, for information on obtaining more digits for the current (or any) date.
DCmplx(X, Y)
DCmplx: COMPLEX(KIND=2)
function.
X: INTEGER
, REAL
, or COMPLEX
; scalar; INTENT(IN).
Y: INTEGER
or REAL
; OPTIONAL (must be omitted if X is COMPLEX
); scalar; INTENT(IN).
Intrinsic groups: f2c
, vxt
.
DConjg(Z)
DConjg: COMPLEX(KIND=2)
function.
Z: COMPLEX(KIND=2)
; scalar; INTENT(IN).
Intrinsic groups: f2c
, vxt
.
Description:
Archaic form of CONJG()
that is specific
to one type for Z.
See section ATan2 Intrinsic.
DFloat(A)
DFloat: REAL(KIND=2)
function.
A: INTEGER
; scalar; INTENT(IN).
Intrinsic groups: f2c
, vxt
.
DImag(Z)
DImag: REAL(KIND=2)
function.
Z: COMPLEX(KIND=2)
; scalar; INTENT(IN).
Intrinsic groups: f2c
, vxt
.
DReal(A)
DReal: REAL(KIND=2)
function.
A: INTEGER
, REAL
, or COMPLEX
; scalar; INTENT(IN).
Intrinsic groups: vxt
.
CALL IDate(D, M, Y)
D: INTEGER(KIND=1)
; scalar; INTENT(OUT).
M: INTEGER(KIND=1)
; scalar; INTENT(OUT).
Y: INTEGER(KIND=1)
; scalar; INTENT(OUT).
Intrinsic groups: vxt
.
Description:
Returns the numerical values of the current local time. The date is returned in D, the month in M (in the range 1--12), and the year in Y (in the range 0--99).
This intrinsic is not recommended, due to the year 2000 approaching. See section IDate Intrinsic, for information on obtaining more digits for the current local date.
Secnds(T)
Secnds: REAL(KIND=1)
function.
T: REAL(KIND=1)
; scalar; INTENT(IN).
Intrinsic groups: vxt
.
Description:
Returns the local time in seconds since midnight minus the value T.
CALL Time(Time)
Time: CHARACTER*8
; scalar; INTENT(OUT).
Intrinsic groups: vxt
.
Go to the first, previous, next, last section, table of contents.