我正在尝试破译 Fortran 代码。它将一个指向函数的指针作为实际参数传递,而形式参数则是一个目标。它在主程序中定义并分配一个 globalDATA 类型的指针,然后调用传递该指针的函数:

module dataGLOBAL
 type globalDATA
   type (gl_1)      , pointer :: gl1
   type (gd_2)      , pointer :: gd2
   type (gdt_ok)    , pointer :: gdtok
   ...
   ...
 end type globalDATA
end module dataGLOBAL


Program main
....
....
use dataGLOBAL
...
type(globalDATA),pointer :: GD

allocate(GD)
returnvalue = INIT(GD)
....
....
end

该函数是这样写的:
integer function INIT(GD) result(returnvalue)
....
....
use dataGLOBAL

type(globalDATA)  , target   :: GD

allocate (GD%gl1)
allocate (GD%gd2)
allocate (GD%gdtok)
....
....
end function INIT

这样做的意义何在?为什么必须分配主程序中的指针和目标结构的单个组件?
谢谢
一种。

最佳答案

一些事情可能会起作用......

  • 当您提供一个指针作为一个过程的实际参数时,其中相应的虚拟参数没有 POINTER 属性(这里的情况),与虚拟参数相关联的东西是实际参数指针的目标。因此,在这种情况下,传递的对象是 GD(在主程序中)指向的对象 - 由分配语句分配的对象。 (当实际参数和虚拟参数都具有 POINTER 参数时,则 POINTER 本身被“传递” - 您可以更改 POINTER 指向的内容,并且该更改会反射(reflect)在调用范围中。)
  • 因为函数内部的 GD 伪参数具有 target 属性,所以函数内部的指针可以指向伪参数。您没有显示此类指针的任何声明,但也许它们在省略的代码中。如果 没有任何 指向 GD 虚拟参数(包括在可能被 INIT 函数调用的任何过程中),那么 TARGET 属性是多余的,但除了抑制某些优化之外无害。
  • 具有指针属性的事物(由语言规则自动)也具有 TARGET 属性 - 因此主程序中的 GD 具有 TARGET 属性。主程序和函数中的 GD 都具有 target 属性这一事实可能是相关的,因为...
  • 当虚拟参数具有 TARGET 属性并且作为实际参数传递的事物具有 TARGET 属性时,则与过程中的虚拟参数关联的指针也“通常”(对于共同索引的事物存在异常(exception)/处理器依赖性/非-与相应的实际参数相关联的连续数组/向量下标部分太复杂了,我记不清了)。如果指针不是局部变量(可能是在模块中声明的指针),则该关联在过程结束后仍然存在。也许这与省略的代码有关。 (或者,如果实际参数没有 TARGET 属性,则在过程结束时与虚拟参数关联的任何指针都将变为未定义。)
  • globalDATA 类型的组件本身就是指针。因此,主程序中的 GD 是一个指向某物(由主程序中的单个 ALLOCATE 语句分配的某物)的指针,它本身包含指向其他事物(由函数中的众多 ALLOCATE 语句分配的那些其他事物)的指针。您有两级指针,因此有两级 ALLOCATE。
  • 在 Fortran 2003(或带有“可分配 TR”的 Fortran 95)之前,派生类型中不能有 ALLOCATABLE 组件,也不能有 ALLOCATABLE 虚拟参数 - 当动态分配的需要与这些以前的限制相冲突时,您必须改用指针,即使您仅将指针用作值。我强烈怀疑您的代码来自这个时代(大约十年前,对可分配 TR 的支持变得普遍)。在非常“现代”的 Fortran 指针中(应该?)仅在您可能想要指向其他事物的变量时使用(其他事物包括“无事物”)。
  • 关于function - Fortran 函数 : pointer as actual argument and target as formal,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14188798/

    10-11 22:59
    查看更多