检查fortran超载任务中的自我分配

时间:2013-11-19 07:27:21

标签: operator-overloading fortran assignment-operator

我正在尝试使用fortran 2003实现一个多项式类,并重载算术运算和赋值。派生类型维护可分配的术语定义和系数列表,如下所示

type polynomial
  private
    type(monomial),dimension(:),allocatable     ::  term
    double precision,dimension(:),allocatable   ::  coef
    integer                                     ::  nterms=0
  contains
   ...
end type polynomial

interface assignment(=)
   module procedure :: polynomial_assignment
end interface
   ...
contains
    elemental subroutine polyn_assignment(lhs,rhs)
      implicit none
      type(polynomial),intent(???)  :: lhs
      type(polynomial),intent(in)   :: rhs
 ...

我必须将它作为元素,因为它旨在用作多项式的矩阵。对大多数情况来说,这确实有效。但是,我在某种程度上让自己陷入了对自我分配的担忧。可以简单地检查指针以查看C ++中的内容是否相同,但它似乎不是Fortran中的选项。但是编译器确实检测到了自我分配并给了我一个警告。 (gfortran 4.9.0)

当我对lhs有 intent(out)时,lhs和rhs的可分配条目似乎在进入子例程时被释放,这是有意义的,因为它们都是p和intent (out)论证首先要完成。

然后我试图避免使用intent(inout)重新分配,并通过修改lhs输出中的一个字段来检查自我赋值

   elemental subroutine polyn_assignment(lhs,rhs)
      implicit none
      type(polynomial),intent(inout)  :: lhs
      type(polynomial),intent(in)   :: rhs
      lhs%nterms=rhs%nterms-5
      if(lhs%nterms==rhs%nterms)then
        lhs%nterms=rhs%nterms+5
        return
      end if
      lhs%nterms=rhs%nterms
嗯,现在这让我感到惊讶。当我做的时候

p=p

它没有进行测试并继续进行,给我一个0项但没有内存违规的多项式。困惑,我在作业中打印了lhs%nterms和rhs%nterms,却发现它们不同!

当我用

做同样的事情时,更令人困惑的是什么
call polyn_assignment(p,p)

它完美地工作并检测到两个参数是相同的。我很困惑一个子程序的接口如何与子程序本身不同地运行。

Fortran 2003中的作业有什么特别之处我错过了吗?

(第一次在这里提问。如果我做得不对,请纠正我。)

1 个答案:

答案 0 :(得分:4)

如果您有一个语句a = b通过子例程sub调用已定义的赋值,则赋值语句等同于call sub(a, (b))。请注意括号 - 右侧参数是评估带括号的表达式的结果,因此在概念上与b不是同一个对象。有关详细信息,请参见F2008 12.4.3.4.3。

因此,a = a相当于call sub(a, (a))。这两个参数没有别名。它与call sub(a,a)不同,后者可能(取决于sub的内部细节,包括伪参数属性)打破Fortran的参数别名规则(例如在您的示例中,语句如{{ 1}}是非法的。)