Some diagnostics produced by g77
require sufficient explanation
that the explanations are given below, and the diagnostics themselves
identify the appropriate explanation.
Identification uses the GNU Info format--specifically, the info
command that displays the explanation is given in within square
brackets in the diagnostic.
For example:
foo.f:5: Invalid statement [info -f g77 M FOOEY]
More details about the above diagnostic is found in the g77
Info
documentation, menu item `M', submenu item `FOOEY',
which is displayed by typing the UNIX command
`info -f g77 M FOOEY'.
Other Info readers, such as EMACS, may be just as easily used to display the pertinent node. In the above example, `g77' is the Info document name, `M' is the top-level menu item to select, and, in that node (named `Diagnostics', the name of this chapter, which is the very text you're reading now), `FOOEY' is the menu item to select.
In this printed version of the g77
manual, the above example
points to a section, below, entitled `FOOEY'---though, of course,
as the above is just a sample, no such section exists.
CMPAMBIG
Ambiguous use of intrinsic intrinsic ...
The type of the argument to the invocation of the intrinsic
intrinsic is a COMPLEX
type other than COMPLEX(KIND=1)
.
Typically, it is COMPLEX(KIND=2)
, also known as
DOUBLE COMPLEX
.
The interpretation of this invocation depends on the particular
dialect of Fortran for which the code was written.
Some dialects convert the real part of the argument to
REAL(KIND=1)
, thus losing precision; other dialects,
and Fortran 90, do no such conversion.
So, GNU Fortran rejects such invocations except under certain circumstances, to avoid making an incorrect assumption that results in generating the wrong code.
To determine the dialect of the program unit, perhaps even whether that particular invocation is properly coded, determine how the result of the intrinsic is used.
The result of intrinsic is expected (by the original programmer)
to be REAL(KIND=1)
(the non-Fortran-90 interpretation) if:
REAL(KIND=1)
.
For example,
a procedure with no DOUBLE PRECISION
or IMPLICIT DOUBLE PRECISION
statement specifying the dummy argument corresponding to an
actual argument of `REAL(Z)', where `Z' is declared
DOUBLE COMPLEX
, strongly suggests that the programmer
expected `REAL(Z)' to return REAL(KIND=1)
instead
of REAL(KIND=2)
.
REAL(KIND=2)
but where treating the intrinsic
invocation as REAL(KIND=2)
would result in unnecessary
promotions and (typically) more expensive operations on the
wider type.
For example:
DOUBLE COMPLEX Z ... R(1) = T * REAL(Z)The above example suggests the programmer expected the real part of `Z' to be converted to
REAL(KIND=1)
before being
multiplied by `T' (presumed, along with `R' above, to
be type REAL(KIND=1)
).
Otherwise, the conversion would have to be delayed until after
the multiplication, requiring not only an extra conversion
(of `T' to REAL(KIND=2)
), but a (typically) more
expensive multiplication (a double-precision multiplication instead
of a single-precision one).
The result of intrinsic is expected (by the original programmer)
to be REAL(KIND=2)
(the Fortran 90 interpretation) if:
REAL(KIND=2)
.
For example, a procedure specifying a DOUBLE PRECISION
dummy argument corresponding to an
actual argument of `REAL(Z)', where `Z' is declared
DOUBLE COMPLEX
, strongly suggests that the programmer
expected `REAL(Z)' to return REAL(KIND=2)
instead
of REAL(KIND=1)
.
REAL(KIND=2)
operands,
or is assigned to a REAL(KIND=2)
variable or array element.
For example:
DOUBLE COMPLEX Z DOUBLE PRECISION R, T ... R(1) = T * REAL(Z)The above example suggests the programmer expected the real part of `Z' to not be converted to
REAL(KIND=1)
by the REAL()
intrinsic.
Otherwise, the conversion would have to be immediately followed
by a conversion back to REAL(KIND=2)
, losing
the original, full precision of the real part of Z
,
before being multiplied by `T'.
Once you have determined whether a particular invocation of intrinsic expects the Fortran 90 interpretation, you can:
COMPLEX(KIND=2)
---if it is
some other type, such as COMPLEX*32
, you should use the
appropriate intrinsic, such as the one to convert to REAL*16
(perhaps DBLEQ()
), in place of DBLE()
.
REAL(KIND=1)
in all working
Fortran compilers.
If you don't want to change the code, and you are certain that all ambiguous invocations of intrinsic in the source file have the same expectation regarding interpretation, you can:
g77
option `-ff90', to enable the
Fortran 90 interpretation.
g77
options `-fno-f90 -fugly-complex',
to enable the non-Fortran-90 interpretations.
See section REAL()
and AIMAG()
of Complex, for more information on this
issue.
Note: If the above suggestions don't produce enough evidence as to whether a particular program expects the Fortran 90 interpretation of this ambiguous invocation of intrinsic, there is one more thing you can try.
If you have access to most or all the compilers used on the program to create successfully tested and deployed executables, read the documentation for, and also test out, each compiler to determine how it treats the intrinsic intrinsic in this case. (If all the compilers don't agree on an interpretation, there might be lurking bugs in the deployed versions of the program.)
The following sample program might help:
PROGRAM JCB003 C C Written by James Craig Burley 1997-02-23. C Contact via Internet email: burley@gnu.ai.mit.edu C C Determine how compilers handle non-standard REAL C and AIMAG on DOUBLE COMPLEX operands. C DOUBLE COMPLEX Z REAL R Z = (3.3D0, 4.4D0) R = Z CALL DUMDUM(Z, R) R = REAL(Z) - R IF (R .NE. 0.) PRINT *, 'REAL() is Fortran 90' IF (R .EQ. 0.) PRINT *, 'REAL() is not Fortran 90' R = 4.4D0 CALL DUMDUM(Z, R) R = AIMAG(Z) - R IF (R .NE. 0.) PRINT *, 'AIMAG() is Fortran 90' IF (R .EQ. 0.) PRINT *, 'AIMAG() is not Fortran 90' END C C Just to make sure compiler doesn't use naive flow C analysis to optimize away careful work above, C which might invalidate results.... C SUBROUTINE DUMDUM(Z, R) DOUBLE COMPLEX Z REAL R END
If the above program prints contradictory results on a particular compiler, run away!
Go to the first, previous, next, last section, table of contents.