Go to the first, previous, next, last section, table of contents.

# The GNU Fortran Compiler

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!

## Compiler Types

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)`
  Same as `float` type.
`REAL(KIND=2)`
  Same as whatever floating-point type that is twice the size of a `float`---usually, this is a `double`.
`INTEGER(KIND=1)`
  Same as an integral type that is occupies the same amount of memory storage as `float`---usually, this is either an `int` or a `long int`.
`LOGICAL(KIND=1)`
  Same `gcc` type as `INTEGER(KIND=1)`.
`INTEGER(KIND=2)`
  Twice the size, and usually nearly twice the range, as `INTEGER(KIND=1)`---usually, this is either a `long int` or a `long long int`.
`LOGICAL(KIND=2)`
  Same `gcc` type as `INTEGER(KIND=2)`.
`INTEGER(KIND=3)`
  Same `gcc` type as signed `char`.
`LOGICAL(KIND=3)`
  Same `gcc` type as `INTEGER(KIND=3)`.
`INTEGER(KIND=6)`
  Twice the size, and usually nearly twice the range, as `INTEGER(KIND=3)`---usually, this is a `short`.
`LOGICAL(KIND=6)`
  Same `gcc` type as `INTEGER(KIND=6)`.
`COMPLEX(KIND=1)`
  Two `REAL(KIND=1)` scalars (one for the real part followed by one for the imaginary part).
`COMPLEX(KIND=2)`
  Two `REAL(KIND=2)` scalars.
`numeric-type*n`
  (Where numeric-type is any type other than `CHARACTER`.) Same as whatever `gcc` type occupies n times the storage space of a `gcc` `char` item.
`DOUBLE PRECISION`
  Same as `REAL(KIND=2)`.
`DOUBLE COMPLEX`
  Same as `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.

## Compiler Constants

`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.

## Compiler Intrinsics

`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.

### Intrinsic Groups

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.

Deleted
  No intrinsics are recognized as belonging to that group.
Disabled
  Intrinsics are recognized as belonging to the group, but references to them (other than via the `INTRINSIC` statement) are disallowed through that group.
Hidden
  Intrinsics in that group are recognized and enabled (if implemented) only if the first mention of the actual name of an intrinsic in a program unit is in an `INTRINSIC` statement.
Enabled
  Intrinsics in that group are recognized and enabled (if implemented).

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`
  Intrinsics the GNU Fortran language supports that are extensions to the Fortran standards (77 and 90).
`f2c`
  Intrinsics supported by AT&T's `f2c` converter and/or `libf2c`.
`f90`
  Fortran 90 intrinsics.
`mil`
  MIL-STD 1753 intrinsics (`MVBITS`, `IAND`, `BTEST`, and so on).
`unix`
  UNIX intrinsics (`IARGC`, `EXIT`, `ERF`, and so on).
`vxt`
  VAX/VMS FORTRAN (current as of v4) intrinsics.

### Other Intrinsics

`g77` supports intrinsics other than those in the GNU Fortran language proper. This set of intrinsics is described below.

#### CDAbs Intrinsic

    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 Intrinsic

    CDCos(X)

CDCos: `COMPLEX(KIND=2)` function.

X: `COMPLEX(KIND=2)`; scalar; INTENT(IN).

Intrinsic groups: `f2c`, `vxt`.

#### CDExp Intrinsic

    CDExp(X)

CDExp: `COMPLEX(KIND=2)` function.

X: `COMPLEX(KIND=2)`; scalar; INTENT(IN).

Intrinsic groups: `f2c`, `vxt`.

#### CDLog Intrinsic

    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 Intrinsic

    CDSin(X)

CDSin: `COMPLEX(KIND=2)` function.

X: `COMPLEX(KIND=2)`; scalar; INTENT(IN).

Intrinsic groups: `f2c`, `vxt`.

#### CDSqRt Intrinsic

    CDSqRt(X)

CDSqRt: `COMPLEX(KIND=2)` function.

X: `COMPLEX(KIND=2)`; scalar; INTENT(IN).

Intrinsic groups: `f2c`, `vxt`.

#### Date Intrinsic

    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 Intrinsic

    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 Intrinsic

    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 Intrinsic

    DFloat(A)

DFloat: `REAL(KIND=2)` function.

A: `INTEGER`; scalar; INTENT(IN).

Intrinsic groups: `f2c`, `vxt`.

#### DImag Intrinsic

    DImag(Z)

DImag: `REAL(KIND=2)` function.

Z: `COMPLEX(KIND=2)`; scalar; INTENT(IN).

Intrinsic groups: `f2c`, `vxt`.

#### DReal Intrinsic

    DReal(A)

DReal: `REAL(KIND=2)` function.

A: `INTEGER`, `REAL`, or `COMPLEX`; scalar; INTENT(IN).

Intrinsic groups: `vxt`.

#### IDate Intrinsic (Form IDATE (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 Intrinsic

    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.

#### Time Intrinsic (Form TIME (VXT))

    CALL Time(Time)

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

Intrinsic groups: `vxt`.

Go to the first, previous, next, last section, table of contents.