我正在尝试使用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中的作业有什么特别之处我错过了吗?
(第一次在这里提问。如果我做得不对,请纠正我。)
答案 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}}是非法的。)