Object-Oriented Fortran: User-defined assignment bindings
Rafik_Zurob 270003B2DK Visits (2019)
Last week, I wrote about user-defined constructors in Fortran 2003. This week, I'd like to discuss user-defined assignment bindings and their role as "copy constructors" for allocatable components.
Like Fortran 90's user-defined assignment interface blocks, Fortran 2003's user-defined assignment bindings define a set of subroutines the compiler must call to perform assignment between objects of two types. User-defined assignment bindings are treated differently from interface blocks when you have intrinsic assignment between types containing allocatable components. Consider the following program which defines an assignment binding for copying objects of type dt1 and a defined assignment interface block for copying objects of type dt2:
module m implicit none type dt1 integer :: data contains procedure assign_dt1 generic :: assignment(=) => assign_dt1 end type type dt2 integer :: data contains procedure assign_dt2 end type type container type(dt1), allocatable :: d1 type(dt2), allocatable :: d2 end type interface assignment(=) module procedure assign_dt2 end interface contains subroutine assign_dt1(to, from) class(dt1), intent(out) :: to type(dt1), intent(in) :: from to%data = from%data + 10 end subroutine subroutine assign_dt2(to, from) class(dt2), intent(out) :: to type(dt2), intent(in) :: from to%data = from%data + 10 end subroutine end module use m implicit none type(container) c1, c2 allocate(c1%d1, source=dt1(3)) allocate(c1%d2, source=dt2(4)) c2 = c1 print *, c2%d1 print *, c2%d2 end
As done last week, I'll use the functrace feature of XLF to show what's going on:
> xlf2003 assi
In the intrinsic assignment between variables c1 and c2, the assignment binding was called for the derived type assignment of c1%d1 to c2%d1. This is not done for user-defined assignment interface blocks. As a result, subroutine assign_dt2 was not called in this program, and intrinsic assignment was used for the derived type assignment of c1%d2 to c2%d2.