Fortran 将指针传递到子例程,xlf和ifort编译器之间的编译差异

Fortran 将指针传递到子例程,xlf和ifort编译器之间的编译差异,fortran,fortran90,intel-fortran,Fortran,Fortran90,Intel Fortran,我很难理解为什么一段Fortran代码在IBM编译器上编译时没有问题,但在英特尔编译器上会出现编译时错误。这段代码是一个较大代码的一部分,它不是由我编写的,但编写这段代码的人主要使用IBM机器 以下函数调用引发错误: call mapsort_qsortRC(map%s(n:m),map%row(n:m),map%col(n:m)) 其中,map类型是一种具有多个字段的自定义数据类型,但相关字段声明为: real ,pointer :: s (:) ! the non-zer

我很难理解为什么一段Fortran代码在IBM编译器上编译时没有问题,但在英特尔编译器上会出现编译时错误。这段代码是一个较大代码的一部分,它不是由我编写的,但编写这段代码的人主要使用IBM机器

以下函数调用引发错误:

call mapsort_qsortRC(map%s(n:m),map%row(n:m),map%col(n:m))
其中,
map
类型是一种具有多个字段的自定义数据类型,但相关字段声明为:

 real   ,pointer :: s  (:)      ! the non-zero matrix elements
 integer,pointer :: row(:)      ! matrix row corresponding to each element
 integer,pointer :: col(:)      ! matrix col corresponding to each element
子例程
mapsort\qsortRC
声明为

recursive SUBROUTINE mapsort_qsortRC(S,row,col)

   implicit none

   !--- arguments ---
   real   (R8) ::   S(:)
   integer(IN) :: row(:),col(:)
精度类型
R8
定义为

integer,parameter :: R8 = selected_real_kind(12) ! 8 byte real

英特尔编译器针对
map
数据类型的变量
S
引发错误“实际参数的类型不同于伪参数的类型”。我可以看到,我们正在将一个
real,指针
传递给一个需要
real
的参数,但我不熟悉fortran中的指针。但更重要的是,一个编译器如何处理它,而另一个编译器如何处理它?

这里的问题与
指针和
非指针无关。当一个指针(如
map%s
(一种类型的指针组件))在一个过程中被引用以与一个伪参数相关联,而该伪参数没有
pointer
属性时,它就是与该伪参数相关联的指针的目标

你们真正的问题在于争论的类型

组件
s
,虽然是指针,但默认为实数。子例程的伪参数是实数,但实数类型为
R8
。对于某些处理器,默认实数的种类值与种类为
R8
的实数的种类值相同。对一些人来说,情况并非如此。您被困在这两种情况之间——要么是通过编译器的设计,要么是通过您使用的标志

对于编译器标志,通常情况下,将默认实数提升为二倍、四倍等,精度不会改变给定显式种类值的那些变量的相应种类-即使这些种类值与默认实数的种类值相同


因此,为了使代码更加便携,请考虑将组件<代码> S/<代码>作为<代码>实际(R8)< /代码> .< /p>如果使用每个编译器,则执行“代码>类(0))/>代码>和代码>类(0。结束
@francescalus您的评论促使我查看编译器标志的实际大小。原来ibm编译器被传递了一个
-qrealsize=8
标志。将
-real size 64
传递给英特尔编译器可修复此问题。我真傻!一点也不傻。我更喜欢建议人们一致地使用种类说明符,而不是依赖于编译器标志。演示得很好!从长远来看,整数组件/参数也存在同样的问题。虽然到目前为止这还不是一个问题,但也可以一贯地为它们提供种类。