Fortran 将可分配变量传递到具有不可分配参数的子例程中会产生什么效果?
假设我们有这个变量定义Fortran 将可分配变量传递到具有不可分配参数的子例程中会产生什么效果?,fortran,Fortran,假设我们有这个变量定义 Real*8, Dimension(:), Allocatable :: dblA Allocate (dblA(1000)) 现在我调用这个子程序: Call MySub(dblA) 其中: Subroutine MySub(dblA) Real*8, INTENT(Out), DIMENSION(1000) :: dblA End 这种做法的副作用是什么? 我应该避免这种情况吗?如果数组在传递给子例程之前已分配,那么子例程对可分配性没有影响,效果与数组是静态
Real*8, Dimension(:), Allocatable :: dblA
Allocate (dblA(1000))
现在我调用这个子程序:
Call MySub(dblA)
其中:
Subroutine MySub(dblA)
Real*8, INTENT(Out), DIMENSION(1000) :: dblA
End
这种做法的副作用是什么?
我应该避免这种情况吗?如果数组在传递给子例程之前已分配,那么子例程对可分配性没有影响,效果与数组是静态的一样。在您展示给我们的片段中,没有什么可以反对,也没有什么实践可以避免。然而,这些片段实际上做的很少,很容易想到扩展它们的方法来使这个建议无效 现在帮你自己一个忙,改变一下
Real*8, INTENT(Out), DIMENSION(1000) :: dblA
到
因此,无论传递的数组大小如何,子例程都能正常工作。使用dblA
作为伪参数和实际参数的名称可能也是一个坏主意,您只会混淆自己
而且real*8
不是,也从来不是一种符合标准的声明8字节real的方法。关于这一点,请参见此处的大量问题和答案。说明了我想要的一切。不过,为了强调,我将重复一个方面
在调用子例程时,非常需要分配子例程中的可分配数组。[就问题而言,应具有足够的规模。]
为了让这个答案不仅仅是一个评论,我将回答更一般的问题标题。在这之前,我将看看“可分配或不可分配的伪参数”思想中可能出现的问题
- 因为伪参数(子例程中的参数)具有
属性,所以它和实际参数变得未定义。如果伪参数是可分配的,则它也会在条目上解除分配。在本例中,实际参数保持分配状态,并保持其原始大小intent(out)
- 如果不可分配,则虚拟参数(和实际参数)不能查询或更改分配状态;伪参数不能进一步传递给期望可分配参数的过程,即使实际参数可以是
- 如果伪参数是可分配的,而不是(静态)显式形状数组,则实际参数也必须是可分配数组
- 对于可分配的伪参数,当引用子例程时,需要显式接口。[有些人会说,即使在隐式接口很好的情况下,这也是一个好主意。]
哦,还有一件事我要从另一个答案中扣除:
Real*8
应该避免。是的,这就是我一直在想的东西,但是太无聊了,写不出来……:-(@Francescalus,你是说意图应该是INOUT吗?一点也不,@Holmz。意图应该是适合使用伪参数(或其他设计考虑因素)的任何东西。对于可分配的伪参数,INTENT(out)
和INTENT(INOUT)
之间的区别要大得多(前者意味着进入时取消分配)比显式形状数组的情况要好。如果你告诉我答案中的哪一点导致了你的问题,我将了解如何澄清。这甚至可以帮助原始询问者。@francescalus在ifort上,数组的尺寸在aubroutine内部是未知的,没有意图(INOUT),这就是问题所在。我的愿望是使用OUT,但我发现INOUT经常是需要的。@Holmz,当有一个显式的shape数组伪参数(如在原始问题中)或一个假定的shape数组时,不必使用intent(INOUT)
来定义伪参数的边界(即有效)参数可用。对于可分配(指针)伪参数,有效参数在进入子例程时被解除分配(相应地,变为未定义的关联状态)-丢失形状细节。看不到您的代码(可能有问题,但可能脱离主题)我不能再多说了。请注意,real*8
不是有效的Fortran,也从来不是任何ISO Fortran/Fortran标准的一部分。请使用内部模块ISO\u Fortran\u env
或selected\u real\u kind
中的命名常量,以便以可移植的方式控制精度。
Real*8, INTENT(Out), DIMENSION(:) :: dblA