Fortran函数:指针作为实际参数,目标为正式 [英] Fortran function: pointer as actual argument and target as formal

查看:203
本文介绍了Fortran函数:指针作为实际参数,目标为正式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  module dataGLOBAL 
类型globalDATA
类型(gl_1),指针:: gl1
类型(gd_2),指针:: gd2
类型(gdt_ok),指针:: gdtok
.. 。
...
结束类型globalDATA
结束模块dataGLOBAL


程序主体
....
.. ..
use dataGLOBAL
...
type(globalDATA),pointer :: GD

allocate(GD)
returnvalue = INIT(GD)
....
....
结束

该函数读取:

 整数函数INIT(GD)结果(返回值)
....
....
use dataGLOBAL

type(globalDATA),target :: GD

allocate(GD%gl1)
allocate(GD%gd2 )
分配(GD%gdtok)
....
....
结束函数INIT

这样做的意义是什么?为什么主程序中的指针和目标结构的单个组件都必须分配?
thanks
A。

解决方案

几件事情可能会发挥作用...




  • 将指针作为实际参数提供给相应的伪参数不具有POINTER属性(此处为案例)的过程时,与伪参数关联的东西是实际参数指针的目标。所以在这种情况下,被传递的对象是 GD (在主程序中)指向的对象 - 由allocate语句分配的对象。 (当实际参数和虚拟参数都具有POINTER参数时,POINTER本身就是通过的 - 您可以更改POINTER指向的内容,并且该更改将反映回调用范围中。)


  • 因为函数中的 GD 伪参数具有target属性,函数中的指针可以指向伪参数。你不会显示这样的指针的任何声明,但也许它们在被遗忘的代码中。如果 nothing 永远指向 GD 伪参数(包括可能由INIT函数调用的任何过程中),则TARGET属性为

  • 具有指针属性的东西(通过语言规则自动)也具有TARGET属性 - 所以<$ c主程序中的$ c> GD 具有TARGET属性。在主程序和函数BOTH中 GD 具有目标属性的事实可能是相关的,因为...


  • <当伪参数具有TARGET属性,并且由于实际参数具有TARGET属性而传递的东西时,那么与过程内的伪参数关联的指针也是通常的(对于coindexed,存在异常/处理器依赖关系与相应的实际参数相关联的东西/不连续的数组/矢量下标段太复杂了,我不记得)。如果一个指针不是一个局部变量(也许它是一个在模块中声明的指针),那么这个关联在过程结束之前仍然存在。也许这在消失的代码中是相关的。 (或者,如果实际参数不具有TARGET属性,那么当过程结束时,与伪参数关联的任何指针都将变为undefined。) globalDATA 类型的组件本身就是指针。因此,主程序中的 GD 是一个指向某个东西的指针(东西被主程序中的单个ALLOCATE语句分配),它本身包含指向其他东西的指针事情由函数中的众多ALLOCATE语句分配)。您有两个级别的指针,因此有两个级别的ALLOCATE。
  • 在Fortran 2003(或带有可分配TR的Fortran 95)之前,您不可能拥有可派生类型中的ALLOCATABLE组件,并且您不能拥有ALLOCATABLE虚拟参数 - 当需要动态分配与前面的限制相冲突时,您必须改用指针,即使您只是将指针用作值。我强烈怀疑你的代码来自这个时代(支持可分配的TR在十年前已经广泛流行)。在非常现代的Fortran指针中,(只有?)只有当你可能需要指向其他事物的变量时(其他事物包括没有事物),才会使用Fortran指针


>

I am trying to decipher a fortran code. It passes a pointer to a function as an actual argument, and the formal argument is instead a target. It defines and allocates a pointer of type globalDATA in the main program, then it calls a function passing that pointer:

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

The function reads:

integer function INIT(GD) result(returnvalue)
....
....
use dataGLOBAL

type(globalDATA)  , target   :: GD

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

What is the meaning of doing this? And why do both the pointer in the main program and the single components of the target structure have to be allocated? thanks A.

解决方案

A few things may come into play...

  • When you provide a pointer as an actual argument to a procedure where the corresponding dummy argument does NOT have the POINTER attribute (the case here), the thing that is associated with the dummy argument is the target of the actual argument pointer. So in this case, the thing being passed is the object that GD (in the main program) is pointing to - the thing that was allocated by the allocate statement. (When both the actual and dummy arguments have the POINTER argument, then the POINTER itself is "passed" - you can change what the POINTER points to and that change is reflected back in the calling scope.)

  • Because the GD dummy argument inside the function has the target attribute, pointers inside the function can be pointed at the dummy argument. You don't show any declarations for such pointers, but perhaps they are in elided code. If nothing is ever pointed at the GD dummy argument (including inside any procedures that might be called by the INIT function), then the TARGET attribute is superfluous, but harmless apart from inhibiting some optimisations.

  • Things that have the pointer attribute also (automatically by language rules) have the TARGET attribute - so GD in the main program has the TARGET attribute. The fact that GD in the main program and in the function BOTH have the target attribute may be relevant because...

  • When the dummy argument has the TARGET attribute and the thing passed as the actual argument has the TARGET attribute, then pointers associated with the dummy argument inside the procedure are also "usually" (there are exceptions/processor dependencies for coindexed things/non-contiguous arrays/vector subscripted sections too complicated for me to remember) associated with the corresponding actual argument. If a pointer is not a local variable (perhaps it is a pointer declared in a module) then this association survives past the end of the procedure. Perhaps that's relevant in the elided code. (Alternatively, if the the actual argument does not have the TARGET attribute, then any pointers associated with the dummy argument become undefined when the procedure ends.)

  • The components of the globalDATA type are themselves pointers. Consequently, GD in the main program is a pointer to something (that something being allocated by the single ALLOCATE statement in the main program) that itself contains pointers to other things (those other things being allocated by the numerous ALLOCATE statements in the function). You have two levels of pointer, hence two levels of ALLOCATE.

  • Before Fortran 2003 (or Fortran 95 with the "allocatable TR") you couldn't have ALLOCATABLE components in derived types, and you couldn't have ALLOCATABLE dummy arguments - when the need for dynamic allocation collided with these former restrictions you had to use pointers instead, even if you were only using the pointers as values. I strongly suspect your code dates from this era (Support for the allocatable TR became widespread about a decade ago). In very "modern" Fortran pointers are (should?) only used when you might want variables that point at other things (where other things includes "no thing").

这篇关于Fortran函数:指针作为实际参数,目标为正式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆