将可分配变量传递给具有不可分配参数的子例程有什么影响?

Sae*_*eid 3 fortran

假设我们有这个变量定义

Real*8, Dimension(:), Allocatable :: dblA
Allocate  (dblA(1000))
Run Code Online (Sandbox Code Playgroud)

现在我调用这个子程序:

Call MySub(dblA)
Run Code Online (Sandbox Code Playgroud)

其中:

Subroutine MySub(dblA)
Real*8,  INTENT(Out), DIMENSION(1000) :: dblA
End
Run Code Online (Sandbox Code Playgroud)

这种做法有什么副作用?我应该避免这个吗?

Hig*_*ark 6

如果在传递给子例程之前已经分配了数组,则子例程与allocatable-ness无关,效果与数组是静态的相同.在你向我们展示的片段中,没有什么可以反对,也没有练习避免.但是,这些片段实际上做得很少,很容易想到扩展它们以使这个建议无效的方法.

现在帮自己一个忙,改变吧

Real*8,  INTENT(Out), DIMENSION(1000) :: dblA
Run Code Online (Sandbox Code Playgroud)

Real*8,  INTENT(Out), DIMENSION(:) :: dblA
Run Code Online (Sandbox Code Playgroud)

这样无论传递的数组大小如何,子程序都能正常工作.使用dblA虚拟和实际参数的名称可能也是一个坏主意,你只会迷惑自己.

并且real*8,并且从来没有,是一种标准兼容的声明8字节实数的方式.关于这一点,请参阅SO上的众多问题和答案.


fra*_*lus 5

高性能马克的回答说明了我想要的一切。不过,为了强调,我将重复一个方面。

非常需要在调用子程序时分配子程序中的可分配数组。[就问题而言,大小足够。]

为了使这个答案不仅仅是一个评论,我将解决更一般的问题标题。在此之前,我将看看围绕“可分配或不可分配虚拟参数”的思考中可能出现的内容。

  • 因为虚拟参数(子例程中的参数)具有intent(out)it 属性,而实际参数则变为未定义。如果虚拟参数是可分配的,那么它也会在进入时被释放。在这种情况下,实际参数保持分配状态并保持其原始大小。

  • 如果虚拟参数(和实际参数)不可分配,则无法查询或更改分配状态;即使实际参数可以,虚拟参数也不能进一步传递给需要可分配参数的过程。

  • 如果虚拟参数是可分配的而不是(静态)显式形状数组,则实际参数也必须是可分配数组。

  • 使用可分配的虚拟参数,在引用子例程时将需要显式接口。[有些人会说,即使在隐式接口很好的情况下,这也是一个好主意。]

谈到更一般的事情,我将举一个例子,其中对可分配的实际/不可分配的虚拟对象有限制(F2008,12.5.2.4):

如果实际参数是多态共索引对象,则虚拟参数不应是多态的。

但对于大多数人来说,这并不是什么值得担心的事情。

哦,还有一件事我会从另一个答案中强调:Real*8应该避免。