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

Passing pointer to subroutine, compilation discrepancy between xlf and ifort compilers

我很难理解为什么一段 Fortran 代码在 IBM 编译器上编译没有问题,但在 intel 编译器上却引发编译时错误。这个片段是一个更大的代码的一部分,不是我写的,但是写这个的人主要使用 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 引发错误 "The type of the actual argument differs from the type of the dummy argument."。我可以看到我们正在将 real, pointer 传递给期望 real 的参数,但我不熟悉 Fortran 中的指针。但更重要的是,一个编译器如何处理得很好,而另一个编译器却不行?

此处的问题与 pointernot-pointer 无关。当一个指针,例如 map%s(类型的指针组件)在过程中被引用以与不带 pointer 属性的伪参数相关联时,它是 目标 作为与虚拟对象关联的参数的指针。

你真正的问题是关于参数的种类

组件s虽然是指针,但默认是实数。子例程的伪参数是实数,但属于实数 R8。对于某些处理器,默认实数与种类实数 R8 具有相同的种类值。对于一些它没有。您被困在这两种情况之间 - 要么是通过编译器的设计,要么是通过您使用的标志。

对于编译器标志,通常情况是将默认实数提升为双倍、四倍等,精度不会更改给定明确种类值的那些变量的相应种类 - 即使这些种类值与默认真实值。

因此,为了使您的代码更具可移植性,请考虑将组件 s 声明为 real(R8)