Arrays Fortran函数:当输出与隐式大小输入相关时的最佳实践

Arrays Fortran函数:当输出与隐式大小输入相关时的最佳实践,arrays,function,fortran,dynamic-allocation,Arrays,Function,Fortran,Dynamic Allocation,例如,我想要一个函数来计算两个矩阵的换向器。我实现它的方式如下: function commutator_dd(MA,MB) > result(MC) implicit none real*8,intent(in) :: MA(:,:) real*8,intent(in) :: MB(:,:) real*8,allocatable :: MC(:,:) real*8,allocatable :: MP(:,:),MN

例如,我想要一个函数来计算两个矩阵的换向器。我实现它的方式如下:

   function commutator_dd(MA,MB)
 > result(MC)
   implicit none
   real*8,intent(in)      :: MA(:,:)
   real*8,intent(in)      :: MB(:,:)
   real*8,allocatable     :: MC(:,:)
   real*8,allocatable     :: MP(:,:),MN(:,:)
   integer                :: nn

   nn=size(MA,1)
   allocate(MC(nn,nn),MP(nn,nn),MN(nn,nn))
   MP=MATMUL(MA,MB)
   MN=MATMUL(MB,MA)
   MC=MP-MN
   return;end function
我的一位朋友指出,也许分配数组而不是取消分配数组不是一个好主意。我倾向于同意这一点,但实际上我不能在返回main之前解除分配MC(我认为fortran在退出过程后会自动解除分配MC,但根据我的记忆,这样离开并不是一个好的做法)。他建议将nn作为函数的输入,并将所有矩阵声明为M(nn,nn),而不是使用分配(或至少使用MC),但我有点不喜欢添加不必要的输入

另一种可能是声明MC(size(MA,1),size(MA,1)),但我以前在这类语法方面遇到过问题(我无法准确指出问题的确切原因,因为使用不同的传递变量的方法总是更容易绕过它,但我记得在尝试这样做时,编译器会抱怨)

哪种方法最好?内在过程(如matmul)以何种方式处理此问题?(我试着在谷歌上搜索matmul的代码,但我发现并不像我预期的那么简单)。

我,我只会使用一个自动数组来返回,就像这样

function commutator_dd(MA,MB) result(MC)
   implicit none
   real*8,intent(in)      :: MA(:,:)
   real*8,intent(in)      :: MB(:,:)
   real*8                 :: MC(size(ma,1),size(ma,2))

   MC=MATMUL(MA,MB)-MATMUL(MB,MA)
   return
end function
如果编译器愿意,让它负责创建临时对象。和您一样,我认为没有必要(从大约Fortran 90开始)在参数列表中包含输入数组的维度。当然,如果输入数组不一致,此代码段不会进行错误检查,并且会失败

如果您的编译器确实抱怨自动调整
MC
的大小,请反馈;我看不出有什么理由这样做。

自动数组(我不确定它是否是函数结果的适当标准术语)是@HighPerformanceMark建议的最佳设计选择,但您甚至不必担心可分配数组

在现代Fortran中,任何可分配的
都是标量或数组,无论是变量还是派生类型组件,任何内存泄漏都是不可能的。除非内存具有save属性(通常用于此目的),否则它总是保证自动释放内存

在本例中,可分配函数结果由调用代码自动解除分配,而临时数组在子例程完成时自动解除分配

还要注意的是,在Fortran 2003中(可分配函数结果仍然需要它),可以省略
allocate
语句。阵列将在
=
分配期间自动分配


摘要:对于任何可分配的
对象,您很少需要
deallocate()
。对于
指针
变量,更常使用它。关于什么是最佳实践-当标准保证了正确的行为时,为什么要用不必要的语句来混乱代码?

在计算MC后,您不能取消分配MP和MN?为什么?是的,我能做到。问题是MC,但你要退回它。取消分配MC不是调用方的工作吗?我相信您从函数返回是MC的一些句柄,而不是整个MC副本。所以调用者必须对MC进行解释并解除分配。MP和MN应在返回之前由被调用方解除分配。Fortran 90(在Fortran 95中更改)中关于自动解除分配的一个特性是“良好实践”的概念。我想你不必担心这个?