class - Fortran函数一次性获取指针的关联状态和大小

标签 class fortran polymorphism intel-fortran

我正在编写一个 Fortran (2003) 整数函数,以使用 class(*) 检查指向任意元素数组的指针的关联状态和大小。如果没有关联,则返回-1,否则返回数组元素的数量。假设定义的指针指向null()

目标是避免两个连续的 if 语句。 (我知道在 C 中,这两个检查可以合并到一个语句中。)

代码在 gfortran (6.1.0) 和 Intel ifort (17.0.4) 下编译并运行,但只有 gfortran 给出了所需的结果。

包含测试例程和名为“size_field”的函数的完整代码如下所示:

program tpa  
implicit none  
real,pointer :: tp(:)=>null()  

                      write (6,*) size_field(tp)  
allocate   (tp(53));  write (6,*) size_field(tp)  
deallocate (tp);      write (6,*) size_field(tp)  
tp=>null();           write (6,*) size_field(tp)  
allocate   (tp(0));   write (6,*) size_field(tp)  
deallocate (tp);      write (6,*) size_field(tp)  

contains

   function size_field(ff)  
   integer :: size_field  
   class(*),target  :: ff(:)  
   class(*),pointer :: field(:)  
   field => ff  
   size_field=-1 ! shall indicate not associated  
   if (associated(field)) size_field=size(field)  
   end function  

end program 

使用gfortran(默认编译器选项)编译,输出如下:

-1
53
-1
-1
 0  
-1  

使用ifort(默认编译选项)编译,输出为:

 0  
53  
53  
53  
 0  
 0  

为什么 ifort 没有给出我想要的结果?
如果我将 class(*) 替换为 real,ifort 编译的程序也会显示正确的结果。

最佳答案

您的程序不是有效的 Fortran。当要求编译该程序时,编译器可以给出任何它喜欢的结果。

虚拟参数ff

   class(*), target :: ff(:)  

是非指针、非可选虚拟参数,因此 (Fortran 2018 15.5.2.3 p1) 引用函数 size_field 时的任何指针实际参数,在本例中为 tp,必须是与目标关联的指针。

在第一个引用上,tp 未关联指针。

至于如何满足您的要求,“非可选”部分是一个很大的提示。在 Fortran 2008+ 下,可以将虚拟参数设置为可选,然后在引用函数时不需要将实际参数与指针关联。如果实际参数未关联指针,则虚拟参数不存在:

function size_field(ff)
  integer :: size_field
  class(*), target, optional :: ff(:)

  if (PRESENT(ff)) then
    size_field = SIZE(ff)
  else
    size_field = -1
  end if

end function

但是,解决该限制的“非可选”部分是解决该问题的唯一有用方法。尝试使虚拟参数成为指针是没有帮助的:对于多态虚拟指针参数,实际参数也必须是多态的(并且对于无限多态虚拟,实际参数也必须是无限多态的)。

关于class - Fortran函数一次性获取指针的关联状态和大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57479760/

相关文章:

python - 在 f2py 中设置 fortran 编译器

c++ - 如何使用 std::vector 作为参数从 Fortran 77 调用 C++ 函数?

将参数转换为泛型变量时的 Java 方法多态性

c# - 没有访客模式的动态调度

python-3.x - 如何在类里面访问或使用名称? Python

java - 向时钟添加时间(不起作用)-JAVA

python - 连接 Python、C 和 Fortran

java - 在Java中设置另一个类中的变量

JavaScript ES2015 : Instanciate a class and use variables from class

rust - 将借用值的向量收集到借用特征的 vec 中