Consider the following Fortran code:
program kinds_demo
use iso_fortran_env, only: REAL64, INT32
integer(int32), parameter :: n=10
real(real64) :: A(n, n)
complex(real64) :: B(n, n)
real(real64) :: tr, u(n*n), v(n*n)
a=1.0D0
b=1.0D0
call dcopy(n*n, a, 1, u, 1)
call dcopy(n*n, b, 2, v, 1)
tr=dot_product(u,v)
print*,tr
end program kinds_demo
I compile it with newest NAG Fortran compiler (NAG Fortran Compiler Release 7.1(Hanzomon) Build 7114)
nagfor -c -o kinds_demo.x kinds_demo.f90
and get this error message
Error: kinds_demo.f90, line 12: Inconsistent data type COMPLEX(KIND(0d0)) (previously DOUBLE PRECISION) for argument 2 in reference to DCOPY
This is an expected error that only becomes evident by comparing the two dcopy
calls. Upon commenting line 11 (first call) the program becomes valid as expected. Notice, I am not linking here. Therefore, the actual type of arguments is irrelevant here, only their consistency matters. But I do not understand the error message. Shouldn't it be written as
Error: kinds_demo.f90, line 12: Inconsistent data type COMPLEX(2) (previously REAL(2)) for argument 2 in reference to DCOPY
Notice that REAL64=2
for the NAG compiler.
It is emphasized many times here that double precision
is not REAL64
, but somehow NAG compiler (which is known for additional error checking and tools capabilities) assumes just opposite?
Kind parameters are numbers. Consider:
where all those expressions for the kind evaluate to
1
. Each of those variables are the same type and kind (default real, kind1
).When a compiler sees a constant expression where a kind parameter is required, it evaluates the expression and uses the value. While a compiler can store the actual constant name/expression used in declaring an object to enhance later error message reporting, this is not common.
Many compilers will complain, not as NAG has chosen with an explanation, simply with the numeric value:
The NAG compiler is choosing to take a value and express it in a more descriptive way with the mapping (using the default 1,2,3 numbering scheme):
(for the "odd" kind 2, note that "double complex" is a non-standard extension offered by compilers other than NAG's and "complex(double precision)" wouldn't work)
Now, we've stressed previously that "double precision" is not "real(128)". By this, we don't mean
kind(0d0)/=real128
, but that the two values aren't necessarily the same. They may be the same.The mapping is intended to be more helpful than a naked number, rather than perfectly expressing the code that was seen (at a different compilation stage). Usually, that's all that's required. Recall that NAG supports different numbering schemes for kinds (
-kind=sequential
,-kind=byte
and-kind=unique
): using the numeric values can cause other confusion.As usual, if you think a compiler's error message could be improved, please do contact the compiler vendor with your suggestion. If the developers agree and see it as worthwhile, perhaps with dozens of other requests, the error message and diagnostics may be changed to what you'd prefer.