Visible to Intel only — GUID: GUID-970CBD6B-00FE-43ED-84C5-ACEB79A36793
Visible to Intel only — GUID: GUID-970CBD6B-00FE-43ED-84C5-ACEB79A36793
Examples of Intrinsic Assignment to Polymorphic Variables
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 and kind types 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.
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
! 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 allocate var with same dynamic type, shape, and size as expr.
Class(*), allocatable :: var(:)
var = [5, 6, 7, 8] ! 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