Reputation: 163
Say I have a Fortran derived type
type :: atype
integer :: n
integer :: a(10)
integer, allocatable :: b(:)
end type
and I have two instances of this type
type(atype) :: t1, t2
what exactly happens when I do the following assignment?
t2 = t1
I am interested in this because I would like to correctly make copies of derived type variables meaning, the scalar components should be equal, each element of array components should be equal and allocatable arrays should have the same allocated size and elements should be equal. At the moment I would just write a subroutine which copies and allocates the components correctly.
subroutine copy_atype(from, to)
type(atype) :: from, to
to%n = from%n
to%a = from%a
if (allocated(to%b)) deallocate(to%b)
if (allocated(from%b) then
allocate(to%b(size(from%b)))
to%b = from%b
end if
end subroutine
I would appreciate directions to appropriate sections in the standards.
I am using gfortran 4.7.
Upvotes: 16
Views: 5276
Reputation: 21451
In the absence of a suitable defined assignment procedure being accessible for the assignment of one atype to another, intrinsic derived type assignment happens. This is described in F2008 7.2.1.3. For your type definition, intrinsic derived type assignment basically does what your procedure does:
The non-allocatable components (that don't themselves have type bound defined assignment) are assigned across using intrinsic assignment. If they do have type bound assignment, that is used.
Allocatable components in the object being assigned to are deallocated if already allocated, reallocated with the same type, type parameters and bounds of the expression being assigned, and then type bound defined assignment (if applicable) or intrinsic assignment is used to transfer the value.
Also:
pointer components are pointer assigned across;
coarray components must match in allocation status between the variable and expression, and are transferred using intrinsic assignment.
Upvotes: 16
Reputation: 18118
This is very similar to a question asked a few days back: Nested derived type with overloaded assignment. See the accepted answer there for a detailed explanation.
You can use you're subroutine copy_atype
directly to form an assignment
operator:
type :: atype
integer :: n
integer :: a(10)
integer, allocatable :: b(:)
contains
procedure :: copy_atype
generic :: assignment(=) => copy_atype
end type
This way, you can directly assign values of the same type to a variable of type atype
. You could even extend the assignment to other types of variables by giving a comma-separated list of appropriate subroutines.
Upvotes: 3