考虑以下Fortran代码:
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
我用最新的NAG Fortran编译器编译它(NAG Fortran compiler Release 7.1(Hanzomon) Build 7114)
nagfor -c -o kinds_demo.x kinds_demo.f90
并得到这个错误信息
错误:kinds_demo。f90,第12行:数据类型不一致参数2的COMPLEX(KIND(0d0))(先前为DOUBLE PRECISION)引用DCOPY
这是一个预期的错误,只有通过比较两个dcopy
调用才会变得明显。在注释第11行(第一次调用)之后,程序按照预期变得有效。注意,我这里没有连读。因此,参数的实际类型在这里是无关紧要的,只有它们的一致性才重要。但是我不理解错误信息。是不是应该写成
错误:kinds_demo。f90,第12行:不一致数据类型COMPLEX(2)(先前为REAL(2)),用于引用DCOPY
的参数2
注意REAL64=2
用于NAG编译器。
这里多次强调double precision
不是REAL64
,但不知为何NAG编译器(以额外的错误检查和工具功能而闻名)假设正好相反?
类型参数为数字。考虑:
use, intrinsic :: iso_fortran_env, only : real32 ! Value 1
use, intrinsic :: iso_c_binding, only : c_float ! Value 1
implicit none
real(kind=1) a
real(kind=5**0) b
real(kind=SELECTED_REAL_KIND(radix=6)) c ! Kind value 1
real(kind=real32) d
real(kind=c_float) e
real f ! Default real has kind 1
end
类型的所有表达式求值为1
。每个变量都是相同的类型和类型(默认为real, kind1
)。
当编译器看到需要类型形参的常量表达式时,它计算该表达式并使用该值。虽然编译器可以存储声明对象时使用的实际常量名称/表达式,以增强以后的错误消息报告,但这并不常见。
许多编译器会报错,而不是像NAG那样选择一个解释,只是用数值:
Error: Type mismatch between actual argument at (1) and actual argument at (2) (COMPLEX(8)/REAL(8)).
NAG编译器选择接受一个值,并通过映射(使用默认的1,2,3编号方案)以更具描述性的方式表示它:
- kind value 1 ->"真正"/"complex">
- 类型值2 ->"双precision"/"复杂(类(0 d0)">
- 类型值3 ->"真正的(real128)";/"复杂(real128)
(for "odd"类2,注意"双重复合";是除NAG和"complex(双精度)"之外的编译器提供的非标准扩展。不会工作)
现在,我们之前已经强调了&;double precision&;不是"真实的"(128)。这里,我们指的不是kind(0d0)/=real128
,而是这两个值不一定相同。它们可能是相同的。
映射的目的是比一个赤裸裸的数字更有帮助,而不是完美地表达所看到的代码(在不同的编译阶段)。通常,这就是所需要的。回想一下,NAG支持不同的种类编号方案(-kind=sequential
,-kind=byte
和-kind=unique
):使用数字值可能会导致其他混淆。