In the project I'm working on, I find myself frequently needing to resize arrays of objects as new objects are created and old ones destroyed. This happens with numerous different derived types throughout the code, most of which have no relationship to each other. It is tedious to write code to resize these arrays for unique derived type, so I thought I'd try writing a couple helper subroutines using unlimited polymorphic dummy arguments so that any derived type array could use those subroutines.
What I've found is that my unlimited polymorphic routine can be compiled and called with CLASS(*),INTENT(INOUT) :: val
. This dummy argument will accept an integer, an allocatable integer, or a pointer to an integer. However, as soon as I try add the ALLOCATABLE
or POINTER
attributes, the subroutine compiles correctly but I cannot call it without obtaining a compiler error. Since my goal is to be able to resize arrays of derived types, these attributes are necessary for the routine to be able to deallocate/allocate/associate the values.
Here's some test code that doesn't even attempt to actually do anything but fails to compile. This version uses scalar concrete types, but the same errors arise in the original code using arrays of concrete types or arrays of derived types
MODULE Resize_mod
PUBLIC
CONTAINS
SUBROUTINE resize(val)
CLASS(*),INTENT(INOUT) :: val
WRITE(*,*) 'resize'
ENDSUBROUTINE resize
SUBROUTINE resize_alloc(val)
CLASS(*),ALLOCATABLE,INTENT(INOUT) :: val
WRITE(*,*) 'resize_alloc'
ENDSUBROUTINE resize_alloc
SUBROUTINE resize_ptr(val)
CLASS(*),POINTER,INTENT(INOUT) :: val
WRITE(*,*) 'resize_ptr'
ENDSUBROUTINE resize_ptr
ENDMODULE Resize_mod
PROGRAM testResize
USE Resize_mod
INTEGER,TARGET :: array0d
INTEGER,ALLOCATABLE :: alloc0d
INTEGER,POINTER :: ptr0d
array0d=1
CALL resize(array0d)
ALLOCATE(alloc0d)
alloc0d=1
CALL resize(alloc0d)
!Following line gives: "Error: Actual argument to ‘val’ at (1) must be polymorphic"
CALL resize_alloc(alloc0d)
ALLOCATE(ptr0d)
ptr0d=1
CALL resize(ptr0d)
!Following line gives: "Error: Actual argument to ‘val’ at (1) must be polymorphic"
CALL resize_ptr(ptr0d)
ENDPROGRAM testResize
As shown, the code produces the following errors:
testResize.f90:31:20:
CALL resize_alloc(alloc0d)
1
Error: Actual argument to ‘val’ at (1) must be polymorphic
testResize.f90:37:18:
CALL resize_ptr(ptr0d)
1
Error: Actual argument to ‘val’ at (1) must be polymorphic
If I comment out the 2 lines named in the errors, I get the following correct output:
resize
resize
resize
I have written Fortran code extensively but have never attempted to use unlimited polymorphism before. Please let me know if what I'm trying to do is possible, and if so, what I am doing wrong.
I am using the gfortran compiler 5.4.0, which should fully support unlimited polymorphism as far as I can tell.