Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28446 Discussions

Polymorphic array initialization problem

Kevin_McGrattan
979 Views

I am having some problems with polymorphic type definitions. I made a slight change to a sample program that Steve Lionel posted years ago:

program PolyArray

    implicit none

    type basetype
       integer :: i=1
    end type basetype

    type, extends(basetype) :: exttype1
       integer :: j=2
    end type exttype1

    type, extends(exttype1) :: exttype2
       integer :: k=3
    end type exttype2

    type arraytype
        class(basetype), allocatable :: comp
    end type arraytype

    type(arraytype), dimension(3) :: ary
    integer :: i

    allocate (basetype::ary(1)%comp)
    allocate (exttype1::ary(2)%comp)
    allocate (exttype2::ary(3)%comp)

     do i=1,3
        select type (st=>ary(i)%comp)
        type is (basetype)
            print 101,i,"basetype"
            print *,ary(i)%comp%i
        type is (exttype1)
            print 101,i,"exttype1"
            print *,ary(i)%comp%j
        type is (exttype2)
            print 101,i,"exttype2"
            print *,ary(i)%comp%k
        class default
            print 101,i,"unknown"
        end select
  101    format ("The dynamic type of ary(",i0,")%comp is ",A)
        end do

end program PolyArray

When I try to compile this code with the latest oneAPI Fortran compiler (ifx version 2021.3.0 Beta), I get the error statements

PolyArray.f90(35): error #6460: This is not a component name that is defined in the encompassing structure.   [J]
            print *,ary(i)%comp%j
--------------------------------^
PolyArray.f90(38): error #6460: This is not a component name that is defined in the encompassing structure.   [K]
            print *,ary(i)%comp%k
--------------------------------^
compilation aborted for PolyArray.f90 (code 1)

 This may not be a problem with the compiler, but rather my understanding of polymorphic derived types. The variable comp is of class(basetype), but I thought that it should "inherit" all the extended type variables as well. That is, in this example, the variable i in the basetype is recognized, but j and k in the type extensions are not.

0 Kudos
1 Solution
Steve_Lionel
Honored Contributor III
971 Views

You want this instead:

        select type (st=>ary(i)%comp)
        type is (basetype)
            print 101,i,"basetype"
            print *,st%i
        type is (exttype1)
            print 101,i,"exttype1"
            print *,st%j
        type is (exttype2)
            print 101,i,"exttype2"
            print *,st%k
        class default
            print 101,i,"unknown"
        end select

 

Since you created an associate name, that's the name that has the selected type.

View solution in original post

3 Replies
Steve_Lionel
Honored Contributor III
972 Views

You want this instead:

        select type (st=>ary(i)%comp)
        type is (basetype)
            print 101,i,"basetype"
            print *,st%i
        type is (exttype1)
            print 101,i,"exttype1"
            print *,st%j
        type is (exttype2)
            print 101,i,"exttype2"
            print *,st%k
        class default
            print 101,i,"unknown"
        end select

 

Since you created an associate name, that's the name that has the selected type.

Kevin_McGrattan
942 Views

As a quick follow-up, how does one invoke, say, ary(2)%comp%j outside of the select type construct?

0 Kudos
Steve_Lionel
Honored Contributor III
908 Views

You can't, because the "declared type" of comp is basetype, which doesn't have a j component.

Reply