Intel® Fortran Compiler 18.0 Developer Guide and Reference
Intrinsic assignment to an allocatable polymorphic variable is allowed. The variable must be type compatible with the expression and of the same rank. If it is allocated but the dynamic type differs from that of the expression, it is deallocated. If it is not allocated or becomes deallocated, it is allocated with the dynamic type of the expression.
Syntax:
assignment-stmt is variable = expr
variable is an allocatable polymorphic and expr is not necessarily an allocatable, but variable and expr must be type compatible.
A polymorphic entity that is not an unlimited polymorphic entity is type compatible with entities of the same declared type or any of its extensions. Even though an unlimited polymorphic entity is not considered to have a declared type, it is type compatible with all entities.
variable and expr must be of the same rank.
If expr is a scalar and variable is allocated, then expr is treated as an array with the same bounds as variable, so the bounds of variable would remain unchanged. It is an error if variable is unallocated when expr is a scalar.
In the examples below, we have the following types:
Type type1 End type Type type2 End type Type, extends(type1) :: type3 End type
Example of same type and same size:
If variable is the same type and size as expr then just do the assignment.
Class(type1), allocatable :: var Class(type1), allocatable :: expr Allocate(expr, source=type1()) Allocate(var, source=type1()) var = expr ! No deallocation of var, simple assignment
Example of same type and different size:
If variable is the same type as expr but their sizes are not the same then deallocate var, reallocate it, and then do the assignment.
Class(type1), allocatable :: var(:) Class(type1), allocatable :: expr(:) Allocate(var(5), source=type1()) Allocate(expr(6), source=type1()) var = expr ! var deallocated and then ! allocated to the size of expr - then ! the usual assignment is performed
Example of different types or shape and same size:
If variable and expr are of different types or shapes but of the same size, then do the assignment and update the type/bounds of var to be same as that of expr, only if type1 and type3 are type compatible.
Class(type1), allocatable :: var(:,:) Class(type1), allocatable :: expr(:,:) Allocate(var(2,3), source=type1()) Allocate(expr(3,2), source=type3()) var = expr ! No deallocation ! simple assignment with var’s ! bounds updated
Example of different types or shape and different size:
If variable and expr are of different types or shapes and of different sizes, then deallocate var and allocate it with the same type and shape as expr, only if type1 and type3 are type compatible.
Class(type1), allocatable :: var(:,:) Class(type3), allocatable :: expr(:,:) Allocate(var(2,4), source=type1()) Allocate(expr(3,3), source=type3()) var = expr ! var deallocated and then ! allocated to the size of expr and ! then the usual assignment var ! has dynamic type set to type3
Example of incompatible types on Left-Hand Side (LHS) and Right-Hand Side (RHS):
If LHS and RHS are type incompatible then you get an error.
Class(type1), allocatable :: var Class(type2), allocatable :: expr Allocate(var,source=type1()) Allocate(expr,source=type2()) var = expr ! This is an error
Example of unallocated allocatable polymorphic on the LHS:
If var is unallocated then expr must be a scalar or it is a shape mismatch error.
Class(*), allocatable :: var(:) var = 5 ! This is an error
Otherwise, allocate var with same dynamic type, shape, and size as expr.
Class(*), allocatable :: var var = 5 ! This is valid
Example of unlimited polymorphic on the LHS:
Unlimited polymorphic allocatable on the LHS is type compatible with any type. If var is of a different size than expr, var is deallocated and then allocated with the type and shape of expr.
Class(*), allocatable :: var Class(type2), allocatable :: expr Allocate(var, source=type1()) Allocate(expr, source=type2()) var = expr ! var is an unlimited polymorphic ! so it is type compatible with ! any type expr