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.
As discussed previously in Variables, there are five built-in data types in Fortran. A derived type is a special form of data type that can encapsulate other built-in types as well as other derived types. It could be considered equivalent to struct in the C and C++ programming languages.
Fortran allows you to define derived data types. A derived data type is also called a structure, and it can consist of data objects of different types.
A derived type is formed by using one or more basic types in combination. Using derived types, an infinite variety of new types can be formed. The array and structure types are collectively called the aggregate types. Note that the aggregate types do not include union types, but a union may contain an aggregate member.
Structures, structured types, or derived types(DT) were first introduced in Fortran 90. Structures allow the user to create data types that hold multiple different variables. Derived types are often implemented within modules such that one can easily reuse them.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With